当前位置: 首页 >数据库 > sql case when用法

sql case when用法

感谢原博主,参考地址https://zhuanlan.zhihu.com/p/110198759?from_voters_page=true

sql case when用法 _ JavaClub全栈架构师技术笔记

case when 是SQL语法中提供的标准的条件分支。
条件分支在MYSQL中即为IF函数,不同的数据库都会提供自己的一些函数,但是CASE WHEN 更加通用。

CASE语句的两种写法

1、搜索CASE表达式

(只会这一种方式即可)

CASE WHEN <求值表达式> THEN <表达式1>WHEN <求值表达式> THEN <表达式2>ELSE <表达式>END

<求值表达式> :一般为字段 【=、>、<、in、等】如 字段 = "1"
<表达式1> : 一般为字段或者字符串或者数值等。

2、简单CASE表达式

CASE <表达式>WHEN <表达式> THEN <表达式>WHEN <表达式> THEN <表达式>ELSE <表达式>END

注:

  1. ELSE 可以不写,默认返回null
  2. end 不可以忘记
  3. 当一个case子句中有多个判断逻辑时、字段类型需要一致
  4. 当一个case子句中有多个判断逻辑时、第一个为真的结果会被输出
  5. 每一个case子句只输出一个结果

case 执行逻辑

case 应用

1、添加列

现有学生表一张

sql case when用法 _ JavaClub全栈架构师技术笔记

先在需要根据生日列 **生成新的一列 **:显示90后,00后,10后

代码:

SELECT s_name,s_birthday ,CASE WHEN YEAR(s_birthday)>=1990 and YEAR(s_birthday)<2000 THEN "90后"WHEN YEAR(s_birthday)>=2000 and YEAR(s_birthday)<2010 THEN "00后"WHEN YEAR(s_birthday)>=2010 and YEAR(s_birthday)<2020 THEN "10后"ELSE "未知"END AS "阶段"from student ;

显示结果:

sql case when用法 _ JavaClub全栈架构师技术笔记

2、行转为列

现统计了学生的总成绩

sql case when用法 _ JavaClub全栈架构师技术笔记


先在想将赵雷和李云的总成绩展示成:

sql case when用法 _ JavaClub全栈架构师技术笔记

可以输入以下代码:

SELECT  SUM(CASE WHEN s_name = "李云" THEN score ELSE 0 END) as "李云",SUM(CASEWHEN s_name = "赵雷" THEN score ELSE 0 END) as "赵雷"FROM score a INNER JOIN student bon a.s_id=b.s_id;

3、实现分组统计

一般我们都使用group by来实现分组统计,但是有的时候需要对字段先分组再统计。

比如我们想知道成绩表现为不及格、良、优秀的课程数分别是多少

3.1 实现人次的分组统计

SELECT CASE WHEN score<60 THEN "不及格"WHEN score>=60 and score<85 THEN "良"WHEN score>=85 THEN "优秀"ELSE "未知"END AS "阶段"  ,count(*) as "人次"from  score a INNER JOIN student b  on a.s_id=b.s_idGROUP BY CASE WHEN score<60 THEN "不及格"WHEN score>=60 and score<85 THEN "良"WHEN score>=85 THEN "优秀"ELSE "未知"END ;

sql case when用法 _ JavaClub全栈架构师技术笔记

因为每个人会参加多门课程,所以当使用count(*)的时候,就是对于人次计算的,学生是没有去重的。

3.2 实现人数的分组统计

SELECT CASE WHEN score<60 THEN "不及格"WHEN score>=60 and score<85 THEN "良"WHEN score>=85 THEN "优秀"ELSE "未知"END AS "阶段",count(DISTINCT a.s_id) as "包含人数" from  score a INNER JOIN student b  on a.s_id=b.s_idGROUP BY CASE WHEN score<60 THEN "不及格"WHEN score>=60 and score<85 THEN "良"WHEN score>=85 THEN "优秀"ELSE "未知"END ;

sql case when用法 _ JavaClub全栈架构师技术笔记

这里使用里count(DISTINCT a.s_id) 对学生进行了去重。

3.3 group by分组中使用别名

SELECT CASE WHEN score<60 THEN "不及格"WHEN score>=60 and score<85 THEN "良"WHEN score>=85 THEN "优秀"ELSE "未知"END AS type,count(*)from  score a INNER JOIN student b  on a.s_id=b.s_idGROUP BY type;

更加SQL执行顺序,是不应该使用别名的,但是在某些,比如MYSQL中执行时会先扫描select后的字段,所以实际执行是可以实现的。

sql case when用法 _ JavaClub全栈架构师技术笔记

4、透视表方式展示

case 表达式可以实现sql像excel透视表类似的功能。

比如我想知道每门课程,学生成绩的分别情况

sql case when用法 _ JavaClub全栈架构师技术笔记

可以使用下方代码进行完成

SELECT c_id,sum(CASE WHEN score<60 THEN 1ELSE 0  END )AS "不及格",sum(CASE WHEN score>=60 and score<85 THEN 1ELSE 0 END) as "良",sum(CASE WHEN score>=85 THEN 1 ELSE 0 END) as "优秀"from  score a LEFT JOIN student bon a.s_id=b.s_idwhere c_id is not nullGROUP BY a.c_id;

case 执行逻辑

1、没有group by 的聚合

上面知识点 行转为列。
代码如下:

SELECT  SUM(CASE WHEN s_name = "李云" THEN score ELSE 0 END) as "李云",SUM(CASEWHEN s_name = "赵雷" THEN score ELSE 0 END) as "赵雷"FROM score a INNER JOIN student bon a.s_id=b.s_id;

结果为

sql case when用法 _ JavaClub全栈架构师技术笔记

我们在语句中使用了聚合函数,这个聚合函数使得数据展示为一行。如果不使用会如何?

sql case when用法 _ JavaClub全栈架构师技术笔记

数据会以每一行的形式展示。
因为SQL在执行完语句后会逐行对数据进行计算。

2、有group by 的汇总数据

接着上面来讲。
这里有个问题,既然用group by了,为何还要使用SUM.。(这里主要是在mysql5.7以下会遇到这样的问题)
我就在实际的统计中,遇到了这样的问题。
因为自己的库装的是mysql,5.8 所以这样不符合规范的代码是运行不了的,因为要修改配置比较麻烦,我这里就手动写出他的

| c_id | 不及格 | 良 | 优秀 | | --- | --- | --- | --- | | 01 | 1 | 0 | 0 | | 02 | 0 | 1 | 0 | | 03 | 1 | 0 | 0 |

这里就会出现每行只有一个结果。

SELECT c_id,CASE WHEN score<60 THEN 1ELSE 0  END AS "不及格",CASE WHEN score>=60 and score<85 THEN 1ELSE 0 END as "良",CASE WHEN score>=85 THEN 1 ELSE 0 END as "优秀"from  score a LEFT JOIN student bon a.s_id=b.s_idwhere c_id is not nullGROUP BY a.c_id;

因为有groupby的存在,很容易导致计算错误还,看不错来,这为一个小坑。

来源链接:https://www.cnblogs.com/javaxubo/p/16862752.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。





本文链接:https://www.javaclub.cn/database/117633.html

标签:group by
分享给朋友: