首页 > 其他分享 >case when最详细用法

case when最详细用法

时间:2022-11-06 16:22:42浏览次数:82  
标签:case CASE END when WHEN 用法 score ELSE id

参考原文:https://zhuanlan.zhihu.com/p/110198759?from_voters_page=true

case when

推荐学习书籍:1SQL基础教程 6-3 2SQL进阶教程 1-1

b29d24326f933451673c71116f0cdb67.png

case whenSQL语法中提供的标准的条件分支。
条件分支在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、添加列

现有学生表一张

e259de871d9239573275f6a1cc04dbcb.png

先在需要根据生日列 **生成新的一列 **:显示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;

显示结果:

8fcc584b5c3a5405504dc3520193fc7b.png

2、行转为列

现统计了学生的总成绩

15980d712fe4f353085c03a44ea7a27f.png


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

5bda37df167cc24a3476080475797da8.png

可以输入以下代码:

SELECT SUM
	( CASE WHEN s_name = "李云" THEN score ELSE 0 END ) AS "李云",
	SUM ( CASE WHEN s_name = "赵雷" THEN score ELSE 0 END ) AS "赵雷" 
FROM
	score
	A INNER JOIN student b ON 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_id 
		GROUP BY
		CASE
				
				WHEN score < 60 THEN "不及格" WHEN score >= 60 
				AND score < 85 THEN "良" WHEN score >= 85 THEN
					"优秀" ELSE "未知" 
	END;

71a74af292307c496a2661d55af3b917.png

因为每个人会参加多门课程,所以当使用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_id 
		GROUP BY
		CASE
				
				WHEN score < 60 THEN "不及格" WHEN score >= 60 
				AND score < 85 THEN "良" WHEN score >= 85 THEN
					"优秀" ELSE "未知" 
	END;

b1c9c0e1cd7a8d640afd3227396876fb.png

这里使用里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_id 
	GROUP BY
	TYPE;

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

319ddf30cb8fadd23c847c794f4d3cd5.png

4、透视表方式展示

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

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

29dbc376d144faee09ef6d0e3f96b1d3.png

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

SELECT
	c_id,
	SUM ( CASE WHEN score < 60 THEN 1 ELSE 0 END ) AS "不及格",
	SUM ( CASE WHEN score >= 60 AND score < 85 THEN 1 ELSE 0 END ) AS "良",
	SUM ( CASE WHEN score >= 85 THEN 1 ELSE 0 END ) AS "优秀" 
FROM
	score
	A LEFT JOIN student b ON A.s_id = b.s_id 
WHERE
	c_id IS NOT NULL 
GROUP BY
	A.c_id;

case 执行逻辑

1、没有group by 的聚合

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

SELECT SUM
	( CASE WHEN s_name = "李云" THEN score ELSE 0 END ) AS "李云",
	SUM ( CASE WHEN s_name = "赵雷" THEN score ELSE 0 END ) AS "赵雷" 
FROM
	score
	A INNER JOIN student b ON A.s_id = b.s_id;

结果为

5bda37df167cc24a3476080475797da8.png

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

c3c231c4b396f7fb82a7c735b5309005.png

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

2、有group by 的汇总数据

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

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

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

SELECT
	c_id,
CASE
		
		WHEN score < 60 THEN 1 ELSE 0 END AS "不及格", CASE WHEN score >= 60 
		AND score < 85 THEN 1 ELSE 0 END AS "良", CASE WHEN score >= 85 THEN
			1 ELSE 0 
			END AS "优秀" 
	FROM
		score
		A LEFT JOIN student b ON A.s_id = b.s_id 
	WHERE
		c_id IS NOT NULL 
GROUP BY
	A.c_id;

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

这里关于SQL的执行顺序还需要单独再进行一章。

标签:case,CASE,END,when,WHEN,用法,score,ELSE,id
From: https://www.cnblogs.com/javaxubo/p/16862903.html

相关文章

  • Xpath用法及其常用函数
    目录XPath简介XPath语法选取节点谓语(Predicates)选取未知节点选取若干路径XPath轴XPATH的几个常用函数XPath简介XPath(XMLPathLanguage)是一门在HTML\XML文档中查找信息......
  • C#中$用法
    一、C#中$的作用$,是C#6.0语法中模板字符串的一种写法。模板字符串是什么?格式化字符串:string.format()这个方法。$是为了替代string.format(),可以把字......
  • Strlen函数用法
    1.strlen的一般用法C库函数 size_tstrlen(constchar*str) 计算字符串 str 的长度,直到空结束字符,但不包括空结束字符。#include<stdio.h>#include<string.h>intma......
  • fetch的基本用法
    fetch可以更加简单的获取数据,可以看作Ajax的升级版,是基于Promise实现的1、使用语法<script>fetch('http://localhost:3000/fdata').then(function(data){......
  • asxio和fetch基本用法
    fetchFetchAPI是新的ajax解决方案Fetch会返回Promisefetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。fetch(url,options).then()<scripttype......
  • Python基础用法
      有人说:一个人从1岁活到80岁很平凡,但如果从80岁倒着活,那么一半以上的人都可能不凡。生活没有捷径,我们踩过的坑都成为了生活的经验,这些经验越早知道,你要走的弯路就会越少......
  • web3-react基本用法
    背景:web3真会玩,除了web3js,etherjs外,又搞出来一个web3-react,看不懂原来是知识盲区。 唤起metamask只需要一个activate方法const{activate}=useWeb3React();cons......
  • etherjs基本用法
    前言:直到2022.11.5才知道etherjs真正的用法,之前只用过web3.js,原来两个库是并行的,选择一个就好。 连接etherjs需要的几要素:infra_keyprivate_keyrpc_url 连接合约......
  • 2、文件操作open,with用法
    """程序的运行是需要消耗内存的内存是软件运行时存储数据的一个地方RAM内存的作用是给CPU的进行任务调度提供资源内存和硬盘是不一样的编码与传输UTF-8程序......
  • 1、python基础用法
    """1.字符串的基础用法str.strip()#去除头尾空格str.split()#以空格为分隔符,包含/nstr.split('',1)#以空格为分隔符,分割一次str.replace(str1,str2,n......