准备数据
创建表:
1 | DROP TABLE IF EXISTS tb_score; |
插入数据:
1 | INSERT INTO tb_score(userid,subject,score) VALUES ('001','语文',90); |
SELECT * FROM tb_score
WITH ROLLUP 的用法
1.WITH ROLLUP:在group分组字段的基础上再进行统计数据。
1 | SELECT userid,IFNULL(`subject`,'total') AS `subject`,SUM(score) AS score |
上面的结果第是为每个userid进行的统计,最后的一列是对所有的total进行的统计
MySQL行转列
要将上面的数据转换成为下面的格式
1、使用case…when…then 进行行转列
1 | SELECT userid, |
2、使用IF() 进行行转列:
1 | SELECT 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、利用SUM(IF()) 生成列 + WITH ROLLUP 生成汇总行
1 | SELECT IFNULL(userid,'total') AS userid, |
MySQL列转行
创建表:
1 | CREATE TABLE tb_score1( |
插入数据:
1 | INSERT INTO tb_score1(userid,cn_score,math_score,en_score,po_score) VALUES ('001',90,92,80,0); |
结果如下:
本质是将userid的每个科目分数分散成一条记录显示出来。
1 | SELECT userid,'语文' AS course,cn_score AS score FROM tb_score1 |
UNION与UNION ALL的区别:
1.对重复结果的处理:UNION会去掉重复记录,UNION ALL不会;
2.对排序的处理:UNION会排序,UNION ALL只是简单地将两个结果集合并;
3.效率方面的区别:因为UNION 会做去重和排序处理,因此效率比UNION ALL慢很多;