求生声明:小弟是个初学者,理解得不到位的地方,欢迎各位大佬指出,必虚心改进,但也拒绝喷子和引战。
注:第一次用掘金编辑器,我是真的不会用。
-------------------------------------------------------------------
## 开篇
在这个碎片化的快节奏时代,慢一点理解一个知识会比知道很多知识更受益。
最近遇到遇到一个很奇葩的需求,作为开发人员我们肯定不能说不行,只能硬着头皮上了。
## 引入一
现在要求每个人的总分数,数据源如下

## 引入二
一个月后新的成绩也出来了,先看图

现在老师想统计 **每个人** 两个月以来的 **各课程** 总分,预期结果如下:

你可能会用行转列完成。
## 奇葩需求
因为语文分数占比大,老师想抓重点。现在要求 **每个人两个月** 的 **语文和数学的总分**,**以及语文的总分**。展示如下图:

你会怎么写?用笔写写伪代码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 还有很多细节,但是网上找不到比较详细的解析。细节语法参考[www.cnblogs.com/eshizhan/ar…]大佬的博客。
终有一天,我会回来研究的,因为对基础的灵活运用是拉近和大佬距离必要条件。
点个关注,下期见!您的支持(关注),是我不断前行最大的动力!
