部分內容有借鑑其他文檔。
行轉列-轉換前:
行轉列-轉換後:
1、使用case...when....then 進行行轉列
SELECT userid,
SUM(CASE `subject` WHEN '語文' THEN score ELSE 0 END) as '語文',
SUM(CASE `subject` WHEN '數學' THEN score ELSE 0 END) as '數學',
SUM(CASE `subject` WHEN '英語' THEN score ELSE 0 END) as '英語',
SUM(CASE `subject` WHEN '政治' THEN score ELSE 0 END) as '政治'
FROM tb_score
GROUP BY userid
2、使用IF() 進行行轉列:
SELECT userid,
SUM(IF(`subject`='語文',score,0)) as '語文',
SUM(IF(`subject`='數學',score,0)) as '數學',
SUM(IF(`subject`='英語',score,0)) as '英語',
SUM(IF(`subject`='政治',score,0)) as '政治'
FROM tb_score
GROUP BY userid
注意點:
(1)SUM() 是爲了能夠使用GROUP BY根據userid進行分組,因爲每一個userid對應的subject="語文"的記錄只有一條,所以SUM() 的值就等於對應那一條記錄的score的值。
假如userid ='001' and subject='語文' 的記錄有兩條,則此時SUM() 的值將會是這兩條記錄的和,同理,使用Max()的值將會是這兩條記錄裏面值最大的一個。但是正常情況下,一個user對應一個subject只有一個分數,因此可以使用SUM()、MAX()、MIN()、AVG()等聚合函數都可以達到行轉列的效果。
(2)IF(`subject`='語文',score,0) 作爲條件,即對所有subject='語文'的記錄的score字段進行SUM()、MAX()、MIN()、AVG()操作,如果score沒有值則默認爲0。
3、列轉行
列轉行-轉換前:
列轉行-轉換後:
SELECT userid,'語文' AS course,cn_score AS score FROM tb_score1
UNION ALL
SELECT userid,'數學' AS course,math_score AS score FROM tb_score1
UNION ALL
SELECT userid,'英語' AS course,en_score AS score FROM tb_score1
UNION ALL
SELECT userid,'政治' AS course,po_score AS score FROM tb_score1
ORDER BY userid
這裏將每個userid對應的多個科目的成績查出來,通過UNION ALL將結果集加起來,達到上圖的效果。
UNION與UNION ALL的區別:
1.對重複結果的處理:UNION會去掉重複記錄,UNION ALL不會;
2.對排序的處理:UNION會排序,UNION ALL只是簡單地將兩個結果集合並;
3.效率方面的區別:因爲UNION 會做去重和排序處理,因此效率比UNION ALL慢很多;
4、利用SUM(IF()) 生成彙總行,並利用 IFNULL將彙總行標題顯示爲Total
SELECT IFNULL(userid,'TOTAL') AS userid,
SUM(IF(`subject`='語文',score,0)) AS 語文,
SUM(IF(`subject`='數學',score,0)) AS 數學,
SUM(IF(`subject`='英語',score,0)) AS 英語,
SUM(IF(`subject`='政治',score,0)) AS 政治,
SUM(score) AS TOTAL
FROM tb_score
GROUP BY userid WITH ROLLUP;
5、利用SUM(IF()) 生成列 + UNION 生成彙總行,並利用 IFNULL將彙總行標題顯示爲 Total
SELECT userid,
SUM(IF(`subject`='語文',score,0)) AS 語文,
SUM(IF(`subject`='數學',score,0)) AS 數學,
SUM(IF(`subject`='英語',score,0)) AS 英語,
SUM(IF(`subject`='政治',score,0)) AS 政治,
SUM(score) AS TOTAL
FROM tb_score
GROUP BY userid
UNION
SELECT 'TOTAL',SUM(IF(`subject`='語文',score,0)) AS 語文,
SUM(IF(`subject`='數學',score,0)) AS 數學,
SUM(IF(`subject`='英語',score,0)) AS 英語,
SUM(IF(`subject`='政治',score,0)) AS 政治,
SUM(score) FROM tb_score
6、合併字段顯示:利用group_concat()
SELECT userid,GROUP_CONCAT(`subject`,":",score)AS 成績 FROM tb_score
GROUP BY userid
group_concat(),手冊上說明:該函數返回帶有來自一個組的連接的非NULL值的字符串結果。
比較抽象,難以理解。通俗點理解,其實是這樣的:group_concat()會計算哪些行屬於同一組,將屬於同一組的列顯示出來。要返回哪些列,由函數參數(就是字段名)決定。分組必須有個標準,就是根據group by指定的列進行分組。
結論:group_concat()函數可以很好的建屬於同一分組的多個行轉化爲一個列。