題目
給定 student_score 表,內容如下:
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
解題
這是一道典型的行轉列題目,給定表中行有學科,而目標表中列是學科。
解法一:case when
通過case when
,可以較容易的實現將行轉換成列的功能,這是通用的思路。
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
解法二:join
解法二和解法三在部分情況下是可行的,用來拓展思路。
--1. 先查詢出每個學科表數據,即獲取一列的數據
select name,score 'y' from student_score where subject = '語文';
select name,score 's' from student_score where subject = '數學';
select name,score 'e' from student_score where subject = '英語';
/*
查詢結果類似如下:
name y
張三 78
李四 89
王五 99
*/
--2. 將第1步查出的三張表進行連接,得出最終結果
SELECT
ss1.NAME,
ss1.y '語文',
ss2.s '數學',
ss3.e '英語'
FROM
( SELECT NAME, score 'y' FROM student_score WHERE SUBJECT = '語文' ) ss1
JOIN ( SELECT NAME, score 's' FROM student_score WHERE SUBJECT = '數學' ) ss2 ON ss1.NAME = ss2.
NAME JOIN ( SELECT NAME, score 'e' FROM student_score WHERE SUBJECT = '英語' ) ss3 ON ss1.NAME = ss3.NAME;
解法三:union all
--1. 第1步和 join 方式一樣,查詢出每個學科表數據
select name,score 'y' from student_score where subject = '語文';
select name,score 's' from student_score where subject = '數學';
select name,score 'e' from student_score where subject = '英語';
/*
查詢結果類似如下:
name y
張三 78
李四 89
王五 99
*/
--2. 通過 union all 將三個表合併起來,並通過 name 進行分組,合併成最終結果
SELECT
s.NAME,
max( s.y ) '語文',
max( s.s ) '數學',
max( s.e ) '英語'
FROM
( SELECT NAME, score y, 0 s, 0 e FROM student_score WHERE SUBJECT = '語文'
UNION ALL
select name,0 y,score s, 0 e from student_score where subject = '數學'
UNION ALL
select name,0 y, 0 s, score e from student_score where subject = '英語' ) s
GROUP BY s.name ;