MySQL数据库case when then end的详细使用方法

 更新时间:2023年12月01日 16:16:18   作者:嘉禾嘉宁papa  
在SQL语法中我们首先使用CASE关键字开头,然后根据不同的条件使用WHEN关键字,并在每个条件后面指定结果,这篇文章主要给大家介绍了关于MySQL数据库case when then end的详细使用方法,需要的朋友可以参考下

一、简介

今天我们主要是讲讲case…when…then…end的用法,它主要分成两类:

  • 简单Case函数
  • Case搜索函数

假设我们数据库有一个员工信息表表如下:

CREATE TABLE `tb_employee` (
  `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `emp_code` int unsigned NOT NULL DEFAULT '0' COMMENT '员工编码',
  `emp_name` varchar(20) NOT NULL DEFAULT '' COMMENT '员工姓名',
  `gender` char(1) NOT NULL DEFAULT '1' COMMENT '性别(1:男0:女)',
  `dep_code` int NOT NULL DEFAULT '0' COMMENT '部门',
  `job` varchar(20) NOT NULL DEFAULT '' COMMENT '工作',
  `age` tinyint NOT NULL DEFAULT '0' COMMENT '年龄',
  `salary` double(8,2) NOT NULL DEFAULT '0.00' COMMENT '工资',
  `hire_date` date DEFAULT NULL COMMENT '入职时间',
  `manage_code` int DEFAULT NULL COMMENT '所属领导',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_emp_code` (`emp_code`),
  KEY `idx_manage_code` (`manage_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='员工信息表';

接下来希望你看文章时不要因为sql长而害怕,都是些重复的东西而已,请放宽心态看待。

二、简单Case函数

2.1、语法定义

语法如下:

CASE '字段名' 
	 WHEN '字段值1' THEN '结果1' 
     WHEN '字段值2' THEN '结果2'
     WHEN '字段值3' THEN '结果3'
     ELSE '其他结果'
END 

字段名 就是数据库表中字段, 字段值 就是这个字段存储的值, 结果 就是你希望得到的结果。

2.2、简单函数形式

比如我们要 查询一份基本的员工信息 ,数据库里存储的是1或者0,我们肯定不会显示1或者0,而是对应的性别(男或者女),这样更加的直观。从上面 tb_student 表的定义我们知道字段 gender ,1表示男,0表示女,默认值是1,这个时候我们就可以利用 case…when…then…end 来实现

SELECT 
	emp_code AS '员工编号',
	emp_name AS '员工姓名',
	(CASE gender
		WHEN 1 THEN '男'
	    WHEN 0 THEN '女'
	    ELSE '未知'
	END) AS '性别',
	salary AS '工资'
FROM tb_employee;

还有些人觉得 else 可以不要,但是不建议这样做,假设数据库没有设置默认值,程序又没有设置值,那就变成空了,又或者有个傻瓜蛋把 gender 的值改成了2呢?毕竟 else 是你的一个兜底。尤其是在一些字段可能会扩展的类型的时候, else 就显得很重要了。

  一般会把 case 到 end 用括号包括,这样也便于解读或者使用别名等。

三、Case搜索函数

3.1、语法定义

语法如下:

CASE WHEN '表达式1' THEN '结果1' 
     WHEN '表达式2' THEN '结果2'
     WHEN '表达式3' THEN '结果3'
     ELSE '其他结果'
END

字段名 就是数据库表中字段, 字段值 就是这个字段存储的值, 结果 就是你希望得到的结果。在Case函数中,表达式可以使用 BETWEEN,LIKE,IS NULL,IN,EXISTS 等等

3.2、简单用法

比如我们还是用 查询一份基本的员工信息 举例看基本使用。

SELECT 
	emp_code AS '员工编号',
	emp_name AS '员工姓名',
	(CASE 
		WHEN gender=1 THEN '男'
	    WHEN gender=0 THEN '女'
	    ELSE '未知'
	END) AS '性别',
	salary AS '工资'
FROM tb_employee;

这样你会发现和上面简单Case函数形式差别很小,确实,如果只是等值表达式,区别很小,并且简单表达式还简单些。这里这么写只是先混个脸熟,根本没有把表达式的作用发挥出来。

3.3、分组

老板想看看公司里员工的薪资架构是否合理, 需要提供一份明细,查询每个人对应的级别 ,级别规划如下:

工资范围工资级别
员工工资小于3000的入门
员工工资大于等于3000并且小于15000的初级
员工工资大于等于15000并且小于25000的中级
员工工资大于等于25000并且小于50000的高级
员工工资大于等于50000特级

则我们可以使用 case…when…then…end 这一语法完成这个查询。

 SELECT 
	emp_code AS '员工编号',
	emp_name AS '员工姓名',
    salary AS '员工工资',
	(CASE 
		WHEN salary < 3000 THEN '入门级'
		WHEN salary >= 3000 AND salary < 15000 THEN '初级'
        WHEN salary >= 15000 AND salary < 25000 THEN '中级'
	    WHEN salary >= 25000 AND salary < 50000 THEN '高级'
	    ELSE '特级'
	END) AS '工资级别'
FROM tb_employee;

这里的表达式,使用了算术表达式,and表达式,还要between…and 表达式,这里只是告诉大家可以用,实际没必要混着用。

3.4、分组+计数

老板想看看 公司对应的每个工资级别分别有多少人 。

SELECT 
	(CASE 
		WHEN salary < 3000 THEN '入门级'
		WHEN salary >= 3000 AND salary < 15000 THEN '初级'
        WHEN salary >= 15000 AND salary < 25000 THEN '中级'
	    WHEN salary >= 25000 AND salary < 50000 THEN '高级'
	    ELSE '特级'
	END) as 'levels',
    count(*) AS '总人数'
FROM tb_employee
GROUP BY levels;

如果老板还想 细分到每个部门,及每个部门对应工资级别的总人数 ,假设部门编号从10到14分别对应则:

编号部门
10总经办
11财务
12技术
13测试
14运维

那么我们只需要先按部门分组,再按工资级别分组即可

SELECT 
	dep_code AS '部门编号',
	(CASE 
		WHEN dep_code=10 THEN '总经办'
		WHEN dep_code=11 THEN '财务'
		WHEN dep_code=12 THEN '技术'
		WHEN dep_code=13 THEN '测试'
		WHEN dep_code=14 THEN '运维'
		ELSE '其他'
		END) AS '部门',
	(CASE 
		WHEN salary < 3000 THEN '入门级'
		WHEN salary >= 3000 AND salary < 15000 THEN '初级'
        WHEN salary >= 15000 AND salary < 25000 THEN '中级'
	    WHEN salary >= 25000 AND salary < 50000 THEN '高级'
	    ELSE '特级'
	END) AS 'levels',
    count(*) as '总人数'
FROM tb_employee
GROUP BY dep_code,levels;

实际中对应部门名称肯定是以连表查询居多,我这里是为了演示,顺便加深 case…when…then…end 用法的使用

3.5、分组+汇总

如果老板现在想知道, 每个部门的总工资,及每个部门中每个工资级别每个月总工资是多少 。小伙伴们想到的可能是先按部门分组,再按性别分组,然后再汇总。如果是一条记录显示这个结果,我相信很多小伙伴也不知道怎么去查询。

我们不着急,我们先查个简单的,查询每个部门的男生总数和女生总数,以及部门的总人数。那么 case…when…then…end 的作用又来了。

SELECT 
	dep_code AS '部门编号',
	(CASE 
		WHEN dep_code=10 THEN '总经办'
		WHEN dep_code=11 THEN '财务'
		WHEN dep_code=12 THEN '技术'
		WHEN dep_code=13 THEN '测试'
		WHEN dep_code=14 THEN '运维'
		ELSE '其他'
	END) AS '部门',
    SUM((CASE WHEN gender = 1 THEN 1 ELSE 0 END)) AS '男生人数',
    SUM((CASE WHEN gender = 0 THEN 1 ELSE 0 END)) AS '女生人数',
    COUNT(*) AS '部门总人数'
FROM
    tb_employee
GROUP BY dep_code;

也许即算看了代码,也许还是有不理解的,为什么两个总数在一行。

  • count(*)按部门分组,同一个部门的每一条记录都会加入结果集
  • case…when…then…end这个是同一个部门中,只有满足条件才会记录到结果集,我们这里满足就记为1,不满足,记为0,然后使用sum函数汇总

了解了上面这个后,我们之前那个需求 每个部门的总工资,及每个部门中每个工资级别每个月总工资是多少 就容易理解了,查询如下:

SELECT 
    dep_code AS '部门编号',
	(CASE 
		WHEN dep_code=10 THEN '总经办'
		WHEN dep_code=11 THEN '财务'
		WHEN dep_code=12 THEN '技术'
		WHEN dep_code=13 THEN '测试'
		WHEN dep_code=14 THEN '运维'
		ELSE '其他'
	END) AS '部门',
	SUM(salary) AS '总工资',
    SUM((CASE WHEN salary <= 3000 THEN salary ELSE 0 END)) AS '入门总工资',
    SUM((CASE WHEN salary > 3000 AND salary < 15000 THEN salary ELSE 0 END)) AS '初级总工资',
    SUM((CASE WHEN salary >= 15000 AND salary < 25000 THEN salary ELSE 0 END)) AS '中级总工资',
    SUM((CASE WHEN salary >= 25000 AND salary <= 50000 THEN salary ELSE 0 END)) AS '高级总工资',
    SUM((CASE WHEN salary > 50000 THEN salary ELSE 0 END)) AS '特级总工资'
FROM
    tb_employee
GROUP BY dep_code;

其实还算可以更详细 每个部门的总人数,总工资,及每个部门中每个工资级别的人数及每个级别对应的总工资是多少

SELECT 
    dep_code AS '部门编号',
	(CASE 
		WHEN dep_code=10 THEN '总经办'
		WHEN dep_code=11 THEN '财务'
		WHEN dep_code=12 THEN '技术'
		WHEN dep_code=13 THEN '测试'
		WHEN dep_code=14 THEN '运维'
		ELSE '其他'
	END) AS '部门',
	COUNT(*) AS '总人数',
	SUM(salary) AS '总工资',
    SUM((CASE WHEN salary <= 3000 THEN 1 ELSE 0 END)) AS '入门总人数',
    SUM((CASE WHEN salary > 3000 AND salary < 15000 THEN 1 ELSE 0 END)) AS '初级总人数',
    SUM((CASE WHEN salary >= 15000 AND salary < 25000 THEN 1 ELSE 0 END)) AS '中级总人数',
    SUM((CASE WHEN salary >= 25000 AND salary <= 50000 THEN 1 ELSE 0 END)) AS '高级总人数',
    SUM((CASE WHEN salary > 50000 THEN 1 ELSE 0 END)) AS '特级总人数',
    SUM((CASE WHEN salary <= 3000 THEN salary ELSE 0 END)) AS '入门总工资',
    SUM((CASE WHEN salary > 3000 AND salary < 15000 THEN salary ELSE 0 END)) AS '初级总工资',
    SUM((CASE WHEN salary >= 15000 AND salary < 25000 THEN salary ELSE 0 END)) AS '中级总工资',
    SUM((CASE WHEN salary >= 25000 AND salary <= 50000 THEN salary ELSE 0 END)) AS '高级总工资',
    SUM((CASE WHEN salary > 50000 THEN salary ELSE 0 END)) AS '特级总工资'
FROM
    tb_employee
GROUP BY dep_code;

相当于两个例子合并了,还可以计算平均工资等就不一一列举了。

3.6、更新语句

公司部门编号从10到20,公司对员工的工资进行调整,除去部门10以外

工资范围工资级别
员工工资小于3000的涨薪400
员工工资大于等于3000并且小于15000的涨薪20%
员工工资大于等于15000并且小于25000的涨薪10%
员工工资大于等于25000并且小于50000的不变
员工工资大于等于50000降薪10%
UPDATE tb_employee 
SET 
    salary = (CASE
        WHEN salary <= 3000 THEN salary + 400
        WHEN salary > 3000 AND salary <= 15000 THEN salary * 1.2
        WHEN salary > 15000 AND salary < 25000 THEN salary * 1.1
        WHEN salary > 50000 THEN salary * 0.9
        ELSE salary
    END)
where dep_code > 10;

3.7、子查询

比如对账时有本地记录 tb_local_record 和外部记录 tb_outside_record ,通过查询看哪些本地记录没有对应的外部记录。

SELECT 
	tranSeq as '交易流水', 
	(CASE 
		WHEN tranSeq IN (SELECT tranSeq FROM tb_outside_record) THEN '匹配' 
		ELSE '未匹配' 
	END) as '是否匹配' 
FROM tb_local_record; 

或者

SELECT 
	lr.tranSeq as '交易流水', 
	(CASE 
		WHEN EXISTS (SELECT osr.tranSeq FROM tb_outside_record osr 
					WHERE  osr.tranSeq = lr.tranSeq) THEN '匹配' 
		ELSE '未匹配' 
	END) as '是否匹配' 
FROM tb_local_record lr; 

结语

case…when…then…end的用法还有很多,比如还能联合count函数,但是一般有以上的方式,基本上就够你工作所需了。

到此这篇关于MySQL数据库case when then end详细使用方法的文章就介绍到这了,更多相关MySQL case when then end内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL超详细安装配置超详细图文教程(亲测有效)

    MySQL超详细安装配置超详细图文教程(亲测有效)

    这篇文章详细介绍了如何下载、配置和安装MySQL,包括设置环境变量、初始化my.ini文件、开启MySQL服务以及设置密码,此外,还介绍了如何使用Navicat工具连接MySQL数据库,感兴趣的朋友跟随小编一起看看吧
    2024-11-11
  • 关于for update和lock in share mode的区别及说明

    关于for update和lock in share mode的区别及说明

    这篇文章主要介绍了关于for update和lock in share mode的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • mysql odbc字符集设置(中文显示乱码)

    mysql odbc字符集设置(中文显示乱码)

    mysql odbc字符集设置(中文显示乱码),碰到这个问题的朋友可以参考下。
    2011-08-08
  • CentOS7安装MySQL8的超级详细教程(无坑!)

    CentOS7安装MySQL8的超级详细教程(无坑!)

    我们在Linux系统中,如果要使用关系型数据库的话,基本都是用的mysql,这篇文章主要给大家介绍了关于CentOS7安装MySQL8的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • MySQL load语句详细介绍

    MySQL load语句详细介绍

    这篇文章主要介绍了MySQL load语句详细介绍,本文讲解了load的基本语法、文件的路径、配置选项、STARTING LINES选项、TERMINATED LINES选项等内容,需要的朋友可以参考下
    2014-12-12
  • MySQL授权命令grant的使用方法小结

    MySQL授权命令grant的使用方法小结

    这篇文章主要介绍了MySQL授权命令grant的使用方法,本文实例,运行于 MySQL 5.0 及以上版本,介绍了MySQL 赋予用户权限命令的简单格式,本文给大家介绍的非常详细,需要的朋友参考下吧
    2021-12-12
  • MySQL kill不掉线程的原因

    MySQL kill不掉线程的原因

    这篇文章主要介绍了MySQL kill不掉线程的原因,帮助大家更好的理解和学习使用MySQL数据库,感兴趣的朋友可以了解下
    2021-05-05
  • MySQL基本运维命令详解

    MySQL基本运维命令详解

    这篇文章主要介绍了MySQL基本运维命令,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-01-01
  • mysql 5.1版本修改密码及远程登录mysql数据库的方法

    mysql 5.1版本修改密码及远程登录mysql数据库的方法

    这篇文章主要介绍了mysql 5.1版本修改密码及远程登录mysql数据库的方法,需要的朋友可以参考下
    2017-04-04
  • 详解JDBC数据库链接及相关方法的封装

    详解JDBC数据库链接及相关方法的封装

    这篇文章主要介绍了详解JDBC数据库链接及相关方法的封装的相关资料,下面是封装的具体类,用到了泛型和反射,希望能帮助到大家,需要的朋友可以参考下
    2017-08-08

最新评论