mysql行轉列(將同一列下的不同內容的幾行數據,轉換成幾列顯示)、列轉行、行列彙總、合併顯示

部分內容有借鑑其他文檔。

行轉列-轉換前:

行轉列-轉換後:

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()函數可以很好的建屬於同一分組的多個行轉化爲一個列。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章