文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

MySQL之case...when...then...end的详细使用

2023-10-23 09:28

关注

目录

一、简介

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

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

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 genderWHEN 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_employeeGROUP 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_employeeGROUP 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_employeeGROUP 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 '部门',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_employeeGROUP 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_employeeGROUP 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函数,但是一般有以上的方式,基本上就够你工作所需了。

来源地址:https://blog.csdn.net/Alian_1223/article/details/128253574

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-数据库
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯