創建表scores
一、傳統的行列轉換
縱表轉橫表
我們要轉成的橫表是這樣子的:
既然這個表只有兩列,那么可以根據姓名進行分組。先把姓名拼湊出來,后面的分數我們再想辦法。
select 姓名 from scores group by 姓名
結果:
分析:
- 我們先拿到語文這個科目的分數。既然我們用到了group by 語句,這里肯定要用聚合函數來求分數。
- 而且我們只需要語文這一科的成績,分組出來的 一共有 3列 ,分別是 語文、數學、物理 。 那么就需要判斷科目來取分數。
這里符合我們需求的 case 語句就登場了。它和c#中switch-case 作用一樣。
sql case 語句語法:
case 字段 when 值1 then 結果 when 值2 then 結果2 ... else 默認結果 end
select 姓名,SUM(case 課程 when '語文' then 分數 else 0 end) as 語文 from scores group by 姓名
結果:
既然語文的分數取到了,其他科目改變下條件就可以了。
完整的sql:
select 姓名, SUM(case 課程 when '語文' then 分數 else 0 end) as 語文, SUM(case 課程 when '數學' then 分數 else 0 end) as 數學, SUM(case 課程 when '物理' then 分數 else 0 end) as 物理 from scores group by 姓名
橫表轉縱表
我們先把剛剛轉好的表,插入一個新表Scores2中。
select 姓名, SUM(case 課程 when '語文' then 分數 else 0 end) as 語文, SUM(case 課程 when '數學' then 分數 else 0 end) as 數學, SUM(case 課程 when '物理' then 分數 else 0 end) as 物理 into scores2 from scores group by 姓名
我們也先把張三和李四的語文成績查出來。
select 姓名, '語文' as 課程, 語文 as 分數 from scores2
結果:
還有兩科的數據怎么辦呢? 很簡單,我們一個個都查出來,然后用 union all 把他們組合為一張表就可以了。
select 姓名, '語文' as 課程, 語文 as 分數 from scores2 union all select 姓名, '數學' as 課程, 數學 as 分數 from scores2 union all select 姓名, '物理' as 課程, 物理 as 分數 from scores2 order by 姓名 desc
結果:
但是大家有沒有覺得很麻煩呢?別急,我們有更簡單的辦法。下面為大家介紹pivot關系運算符。
pivot是sql server 2005 提供的運算符,所以只要數據庫在05版本以上的都可以使用。主要用於行和列的轉換。
pivot縱表轉橫表
select t2.姓名, t2.數學, t2.物理, t2.語文 from Scores as t1 pivot (sum(分數) for 課程 in(數學,語文,物理)) as t2
pivot將原來表中 課程字段中的 數據行 數學,語文,物理 轉換為列,並用sum取對應列的值。
我們只需要記住它的用法就可以了。
unpivot 橫表轉縱表
select * from scores2 unpivot (分數 for 課程 in (語文,數學,物理)) as t3
unpivot 將 語文,數學,物理 列轉為行,分數為新的一列存放對應的值。