SqlServer⾥巧⽤Case将多⾏显⽰的数据合并为⼀⾏显⽰
昨晚在CSDN论坛上看到有某个⼈问了类似这样的⼀个问题,现有三个数据表,分别是学⽣表,课程表,成绩表。它们的结构与样例数据如下:
学⽣表:
学⽣Id    姓名
1            张三
2            李四
3            王五
课程表:
课程Id    课程名
1            语⽂
2            化学
3            外语
4            物理
成绩表:
学⽣Id    课程Id        成绩
1              1                60
1              2                70
1              3                65
1              4                90
2              1                80
2              2                65
2              3                85
2              4                80
3              1                50
3              2                75
3              3                85
3              4                60
现要求在⼀⾏中输出每个学⽣的所有课程的成绩单,显⽰样例格式如下:
姓名语⽂化学外语物理
张三        60            70          65            90
李四        80            65          85            80
王五        50            75          85            60
当⼤家看到这样的题⽬时会优先考虑到的是怎样的⼀条SQL语句呢?嵌套Select?对,在将⾏转换为
列时,也许这种⽅法是最优先考虑到(或者你是⾼⼿,所以不是优先考虑到这个⽽是其它),所以我最开始也写出了下⾯这条语句:
SELECT B.姓名,
(SELECT成绩FROM成绩表INNER JOIN课程ON成绩表.课程ID=课程.课程ID WHERE成绩表.学⽣ID=B.学⽣ID AND课程.课程名='语⽂' ) AS语⽂,
(SELECT成绩FROM成绩表INNER JOIN课程ON成绩表.课程ID=课程.课程ID WHERE成绩表.学⽣ID=B.学⽣ID AND课程.课程名='化学' ) AS化学,
(SELECT成绩FROM成绩表INNER JOIN课程ON成绩表.课程ID=课程.课程ID WHERE成绩表.学⽣ID=B.学⽣ID AND课程.课程名='外语' ) AS外语,
(SELECT成绩FROM成绩表INNER JOIN课程ON成绩表.课程ID=课程.课程ID WHERE成绩表.学⽣ID=B.学⽣ID AND课程.课程名='物理' ) AS物理
FROM学⽣ B
这样我们的⽬的是达到了,但后来我⼜想了⼀下,因为我们要的数据其实都在成绩表⾥,只不过现有
的是⽤⾏来存放,那我们怎么将它转换为列显⽰呢?嗯,这也许就要搬出聚合函数加Case条件来处理了!最终的SQL语句如下:
SELECT姓名,
MAX(CASE课程名WHEN'语⽂'THEN成绩ELSE0END) AS语⽂,
MAX(CASE课程名WHEN'化学'THEN成绩ELSE0END) AS化学,
MAX(CASE课程名WHEN'外语'THEN成绩ELSE0END) AS外语,
MAX(CASE课程名WHEN'物理'THEN成绩ELSE0END) AS物理
FROM (SELECT B.姓名,C.课程名,D.成绩FROM成绩表 D
INNER JOIN学⽣ B ON B.学⽣ID=D.学⽣ID
INNER JOIN课程 C ON C.课程ID=D.课程ID) AS TMP GROUP BY姓名
运⾏后,也是可以得到正确的数据,下⾯给出测试代码,⼤家可以直接在SQL查询分析器⾥运⾏
CREATE TABLE学⽣ (学⽣ID INT, 姓名VARCHAR(20))
CREATE TABLE课程 (课程ID INT, 课程名VARCHAR(20))
CREATE TABLE成绩表 (学⽣ID INT, 课程ID INT, 成绩INT)
INSERT INTO学⽣
SELECT1,'张三'UNION ALL
SELECT2,'李四'UNION ALL
SELECT3,'王五'
INSERT INTO课程
SELECT1,'语⽂'UNION ALL
SELECT2,'化学'UNION ALL
SELECT3,'外语'UNION ALL
sql中union多表合并SELECT4,'物理'
INSERT INTO成绩表
SELECT1,1,60UNION ALL
SELECT1,2,70UNION ALL
SELECT1,3,65UNION ALL
SELECT1,4,90UNION ALL
SELECT2,1,80UNION ALL
SELECT2,2,65UNION ALL
SELECT2,3,85UNION ALL
SELECT2,4,80UNION ALL
SELECT3,1,50UNION ALL
SELECT3,2,75UNION ALL
SELECT3,3,85UNION ALL
SELECT3,4,60
--⽅法⼀
SELECT B.姓名,
(SELECT成绩FROM成绩表INNER JOIN课程ON成绩表.课程ID=课程.课程ID WHERE成绩表.学⽣ID=B.学⽣ID AND课程.课程名='语⽂' ) AS语⽂, (SELECT成绩FROM成绩表INNER JOIN课程ON成绩表.课程ID=课程.课程ID WHERE成绩表.学⽣ID=B.学⽣ID AND课程.课程名='化学' ) AS化学, (SELECT成绩FROM成绩表INNER JOIN课程ON成绩表.课程ID=课程.课程ID WHERE成绩表.学⽣ID=B.学⽣ID AND课程.课程名='外语' ) AS外语, (SELECT成绩FROM成绩表INNER JOIN课程ON成绩表.课程ID=课程.课程ID WHERE成绩表.学⽣ID=B.学⽣ID AND课程.课程名='物理' ) AS物理FROM学⽣ B
--⽅法⼆
SELECT姓名,
MAX(CASE课程名WHEN'语⽂'THEN成绩ELSE0END) AS语⽂,
MAX(CASE课程名WHEN'化学'THEN成绩ELSE0END) AS化学,
MAX(CASE课程名WHEN'外语'THEN成绩ELSE0END) AS外语,
MAX(CASE课程名WHEN'物理'THEN成绩ELSE0END) AS物理
FROM (SELECT B.姓名,C.课程名,D.成绩FROM成绩表 D
INNER JOIN学⽣ B ON B.学⽣ID=D.学⽣ID
INNER JOIN课程 C ON C.课程ID=D.课程ID) AS TMP GROUP BY姓名
DROP TABLE学⽣
DROP TABLE课程
DROP TABLE成绩表
PS:⽤嵌套SELECT与⽤聚合函数加Case两者的效率如何,我没有测试,各位有兴趣的可测试⼀下

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。