很多时候,我们在开发的时候需要用到SQL行转列或列转行的知识,本文将针对如何在MySQL里实现行和列的互相转换做一些介绍,文中的示例写的还是比较详细的,希望对大家有帮助。
准备测试表数据
假设现在有一张学生成绩表,记录了每个学生不同科目的考试成绩。
1.行转列
现在要进行行转列,达到如下效果,科目由原来的行转为列:
下面就结合该案例介绍几个行转列的方法。
1.1 四种行转列方法
1.1.1 case… when … then … else … end
SELECT
uname,
uid,-- 正常查询的字段
-- 需要转换的字段
sum( CASE WHEN course = '英语' THEN score ELSE 0 END ) '英语',
sum( CASE WHEN course = '物理' THEN score ELSE 0 END ) '物理',
sum( CASE WHEN course = '化学' THEN score ELSE 0 END ) '化学'
FROM
course
GROUP BY
uid;
另一种写法:
case course
when '化学' then score
else 0
end
需要注意的是
- ‘else 0’分支若去掉,那如果某同学没有某课程则分数会显示为null;
- sum替换成max结果一样;
1.1.2 if (column name
=’column value’,,)
SELECT
uname,
uid,
sum( IF ( `course` = '英语', score, 0 ) ) '英语',
sum( IF ( `course` = '物理', score, 0 ) ) '物理',
sum( IF ( `course` = '化学', score, 0 ) ) '化学'
FROM
course
GROUP BY
uname
1和2这两种SQL写法结果是相同的,方法2看着好像比第一种简洁点,下面还有些扩展功能的实现,也是基于该方法来修改的。
1.2 计算每个学生各科的总分和每科所有学生的总分
就像下图,要实现这样的效果。
最右侧的total列实现起来比较简单,在上条SQL的基础上再加个sum(score) 'total'
就可以了;
下方的Total行,其实就是上条SQL不加group by的效果。
所以思路到了这儿就简单了,上图中的效果,我们可以看成下面两张图的查询结果的组合,也就是union一下即可。
1.3 if (column name
=’column value’,,) + union
下面这个sql就是两条查询SQL拼起来的,可以实现上图的效果:
SELECT
uid,
uname,
sum( IF ( `course` = '英语', score, 0 ) ) '英语',
sum( IF ( `course` = '物理', score, 0 ) ) '物理',
sum( IF ( `course` = '化学', score, 0 ) ) '化学',
sum( score ) 'total'
FROM
course
GROUP BY
uname UNION
SELECT
'Total',
NULL,
sum( IF ( `course` = '英语', score, 0 ) ) '英语',
sum( IF ( `course` = '物理', score, 0 ) ) '物理',
sum( IF ( `course` = '化学', score, 0 ) ) '化学',
sum( score ) 'total'
FROM
course
1.4 if (column name
=’column value’,,) + IFNULL()+ with rollup
Mysql中有一个with rollup,可以在分组统计数据的基础上再进行统计汇总,即用来得到group by的汇总信息。
说人话就是会在最下面多出一行,这行是对上面统计数据的汇总。
需要注意的是,某列如果不是数字类型,则多出来的最下面一行的该列会显示为null,所以结合本示例,咱可以搭配 fnull()来优化该sql。
SELECT
ifnull( uid, 'Total' ) uid,
uname,
sum( IF ( `course` = '英语', score, 0 ) ) '英语',
sum( IF ( `course` = '物理', score, 0 ) ) '物理',
sum( IF ( `course` = '化学', score, 0 ) ) '化学',
sum( score ) 'total'
FROM
course
GROUP BY
uid WITH ROLLUP
2.列转行
行转列会了,列转行就简单了,就是按相反的逻辑来可以了,
假设表中的数据是这样的,为了偷懒一下,不创建一个新表,咱可以把上一步查询的SQL改造成一个创建视图的SQL:
CREATE VIEW rtc AS SELECT
ifnull( uid, 'Total' ) uid,
uname,
sum( IF ( `course` = '英语', score, 0 ) ) '英语',
sum( IF ( `course` = '物理', score, 0 ) ) '物理',
sum( IF ( `course` = '化学', score, 0 ) ) '化学',
sum( score ) 'total'
FROM
course
GROUP BY
uid WITH ROLLUP
该临时表的数据就是这样的:
咱需要的转化后的结果是这样的
下面是列转行代码
SELECT
uid,
uname,
'英语' course,英语 score
FROM
rtc
WHERE
uid <> 'Total'
AND 英语 > 0 UNION ALL
SELECT
uid,
uname,
'物理',物理
FROM
rtc
WHERE
uid <> 'Total'
AND 物理 > 0 UNION ALL
SELECT
uid,
uname,
'化学',化学
FROM
rtc
WHERE
uid <> 'Total'
AND 化学 >0
好了,MySQL里如何实现行列转换都已经介绍完了,希望对你能有帮助。
本文由《MySql教程网》原创,转载请注明出处!https://mysql360.com