mysql行转列问题 | 来自一位读者本周五的面试题
罗小黑战记
欢迎点击上方蓝色字体『 Bella的技术轮子 』关注哦~
昨天在家中突然收到一位读者发来的求助信息。
由于这位读者前几天和我说正在面试菜鸟,我下意识的以为是面试题,想要拒绝,因为我的原则是不帮助正在面试中的人,面试后可以讨论自己有疑惑的题。后来发现是读者周五面试的面试题,于是我便开始了安装mysql、可视化客户端、coding。
面试题如下:
不知正在读这篇文章的你,看到此题是否有思路,可以立刻在白板上写出来呢?
最后我回复了这位读者两种写法,简单易懂的&万能通用的 各一种。
1.简单易懂的一种写法,由于一名学生一门课只有一个分数,所以下面sql中max函数完全可以换为sum等其他聚合函数。
select `user_name`,
max(case `subject` when '语文' then IFNULL(`score`, 0) else 0 end) as '语文',
max(case `subject` when '数学' then IFNULL(`score`, 0) else 0 end) as '数学',
max(case `subject` when '英语' then IFNULL(`score`, 0) else 0 end) as '英语',
max(case `subject` when '生物' then IFNULL(`score`, 0) else 0 end) as '生物'
from `sc`
group by `user_name`;
运行结果:
2.不需要提前知道有多少门课程,动态生成列,万能通用的一种写法。
set @splice_sql = null;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT('max(if(subject=''',subject,''', score, 0)) as ''',subject, ''''))
into @splice_sql
from sc;
set @splice_sql = CONCAT('select user_name,', @splice_sql, ' from sc group by user_name');
prepare bella_test from @splice_sql;
execute bella_test;
DEALLOCATE prepare bella_test;
运行结果:
附建表语句&初始化数据语句:
CREATE TABLE `sc` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_name` varchar(32) NOT NULL DEFAULT '',
`subject` varchar(32) NOT NULL DEFAULT '',
`score` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
insert into sc(id,user_name,subject,score)
values (1,"张三","语文",80),(2,"张三","数学",90),(3,"张三","英语",70),(4,"张三","生物",85),
(5,"李四","语文",80),(6,"李四","数学",90),(7,"李四","英语",70),(8,"李四","生物",85);
-END-
更多精彩文章
如果你喜欢本文
请长按二维码,关注 Bella的技术轮子
喜欢就点个在看吧