开篇
在这个碎片化的快节奏时代,慢一点理解一个知识会比知道很多知识更受益。
最近遇到遇到一个很奇葩的需求,作为开发人员我们肯定不能说不行,只能硬着头皮上了。
引入一
现在要求每个人的总分数,数据源如下
引入二
一个月后新的成绩也出来了,先看图
现在老师想统计 每个人两个月以来的 各课程总分,预期结果如下:
你可能会用行转列完成。
奇葩需求
因为语文分数占比大,老师想抓重点。现在要求 每个人两个月的 语文和数学的总分,以及语文的总分。展示如下图:
你会怎么写?用笔写写伪代码SQL吧,自己动手+思考,收获更多。
抛砖引玉
两个子查询,一个子查询计算语文和数学的总分,另一个子查询计算语文的总分,再把两个结果集通过 name链接起来。
但是,我这种写法在实际中并不是最优选择。整个SQL会多做一次I/O,数据量大的话,严重影响性能。经过请教,大佬推荐我使用case when。类似于Java中的switch。
初识case when
case when 表达式是一个通用条件的表达式,可以在表达式有效的任何位置使用。
Case具有两种格式:简单Case函数和Case搜索函数。
简单Case函数:
CASE sex WHEN '1’ THEN '男’ WHEN '0’ THEN '女’ ELSE '其他’ END
Case搜索函数:
CASE WHEN sex = '1’ THEN '男’ WHEN sex = '0’ THEN '女’ ELSE '其他’ END
STOP!请思考两种写法的差异。
显然,简单Case函数生在简洁,但是它只适用于这种单字段的单值比较。
而Case搜索函数的优点在于适用于所有比较的情况。
注:Case函数从上往下执行,在满足了某个符合条件后,剩下的条件将会被自动忽略。因此,即使满足多个条件,执行过程中也只认第一个条件。
完成需求
对于上面奇葩需求的代码实现如下
如果你以为这就结束了,那就你猜错了。
有人应该已经发现了,Chinese的结果是错的。这是因为:
在使用 CASE WHEN时,可以把它当作一个没有字段名的字段,字段值根据条件确认,在需要使用字段名时可以是用 as来定义别名。
我把每一个chinese的值都进行了一次求和,但并没有求出所有chinese的和。当然对于这种错误的逻辑,执行的时候会报错,但它报的是chines字段不是分组字段,后面的剧情你们肯定猜到了,我在外面又进行了一次分组。。。
额,没关系,成长的道路不一定一帆风顺。如果你这时候还希望我摆出正确的写法,那。。。
结语
后面和大佬探讨,从我打算用Group by 完成这个需求时,就已经错了,做再多也不过是曲线救国,正确的思路应该用分析函数。
case when 还有很多细节,但是网上找不到比较详细的解析。细节语法参考https://www.cnblogs.com/eshizhan/archive/2012/04/06/2435493.html大佬的博客。
终有一天,我会回来研究的,因为对基础的灵活运用是拉近和大佬距离必要条件。
点个关注,下期见!您的支持(关注),是我不断前行最大的动力!
扫一扫点个关注吧
联系客服