我的网站已上线:http://javapub.net.cn/
行转列是很常见的一个场景。经典的解决方案是条件聚合,即 sum+if 组合。
也就是长表转宽表
@[toc]
建表
create table test_score
(
id int null,
uid varchar(20) null,
course varchar(20) null,
score int null
);
INSERT INTO `spring-boot-bpmn`.test_score (id, uid, course, score)
VALUES (1, 'tom', 'chinese', 89);
INSERT INTO `spring-boot-bpmn`.test_score (id, uid, course, score)
VALUES (2, 'jetty', 'math', 78);
INSERT INTO `spring-boot-bpmn`.test_score (id, uid, course, score)
VALUES (3, 'tom', 'english', 88);
INSERT INTO `spring-boot-bpmn`.test_score (id, uid, course, score)
VALUES (4, 'jetty', 'chinese', 89);
INSERT INTO `spring-boot-bpmn`.test_score (id, uid, course, score)
VALUES (5, 'jack', 'chinese', 90);
INSERT INTO `spring-boot-bpmn`.test_score (id, uid, course, score)
VALUES (6, 'jack', 'english', 78);
INSERT INTO `spring-boot-bpmn`.test_score (id, uid, course, score)
VALUES (7, 'jack', 'math', 99);
思路 sum+if
- 在长表的数据组织结构中,同一 uid 对应了多行,即每门课程一条记录,对应一组分数,而在宽表中需要将其变成同一 uid 下仅对应一行
- 在长表中,仅有一列记录了课程成绩,但在宽表中则每门课作为一列记录成绩
- 由多行变一行,那么直觉想到的就是要 groupby 聚合;由一列变多列,那么就涉及到衍生提取;
- 既然要用 groupby 聚合,那么就涉及到将多门课的成绩汇总,但现在需要的不是所有成绩汇总,而仍然是各门课的独立成绩,所以需要用一个 if 函数加以筛选提取;当然,用 case when 也可以;
- 在 if 筛选提取的基础上,针对不同课程设立不同的提取条件,并最终加一个聚合函数提取该列成绩即可。
sql代码
select uid,
sum(if(course = 'chinese', score, null)) as 'chinses',
sum(if(course = 'math', score, null)) as 'math',
sum(if(course = 'english', score, null)) as 'english'
from test_score
group by uid;
宽表
更多sql:https://blog.csdn.net/qq_40374604/category_11803603.html