此文以一個實際的查詢問題為例說明,MySQL中的行轉列問題怎么解決。
一、問題
表:student
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| name | varchar |
| continent | varchar |
+-------------+---------+
該表沒有主鍵。它可能包含重復的行。
該表的每一行表示學生的名字和他們來自的大陸。
一所學校有來自亞洲、歐洲和美洲的學生。
寫一個查詢語句實現對大洲(continent)列的 透視表 操作,使得每個學生按照姓名的字母順序依次排列在對應的大洲下面。輸出的標題應依次為美洲(America)、亞洲(Asia)和歐洲(Europe)。
測試用例的生成使得來自美國的學生人數不少于亞洲或歐洲的學生人數。
查詢結果格式如下所示。
示例 1:
輸入:
Student table:
+--------+-----------+
| name | continent |
+--------+-----------+
| Jane | America |
| Pascal | Europe |
| Xi | Asia |
| Jack | America |
+--------+-----------+
輸出:
+---------+------+--------+
| America | Asia | Europe |
+---------+------+--------+
| Jack | Xi | Pascal |
| Jane | null | null |
+---------+------+--------+
二、思路
第一步:
按照continent分組,按照NAME排序,增加一列,命名為rk。
SELECT *, ROW_NUMBER() OVER (PARTITION BY continent ORDER BY NAME) rk FROM student
第二步:
按照rk分組,max進行 行轉列
SELECT
MAX(CASE continent WHEN 'America'THEN NAME ELSE NULL END) AS America,
MAX(CASE continent WHEN 'Asia'THEN NAME ELSE NULL END) AS Asia,
MAX(CASE continent WHEN 'Europe'THEN NAME ELSE NULL END) AS Europe
FROM
(SELECT *, ROW_NUMBER() OVER (PARTITION BY continent ORDER BY NAME) rk FROM student) t
GROUP BY rk
三、知識點
1.行轉列最常見的方法是
group by+sum/max/min(case when)
select * from student_score;
nane subject score
-------------------------------
張三 語文 78
張三 數學 88
張三 英語 98
李四 語文 89
李四 數學 76
李四 英語 90
王五 語文 99
王五 數學 66
王五 英語 91
要求用一條 sql 語句查出如下結果:
姓名 語文 數學 英語
張三 78 88 98
李四 89 76 90
王五 89 56 89
語句為:SELECT NAME,
max( CASE SUBJECT WHEN '語文' THEN score END ) '語文',
max( CASE SUBJECT WHEN '數學' THEN score END ) '數學',
max( CASE SUBJECT WHEN '英語' THEN score END ) '英語'
FROM
student_score
GROUP BY
NAME
2.原表格沒有基準id或者基準列需要自己構造,比如上面問題的rk列,相當于知識點第一點舉例中的name列。