专栏首页码海Mysql 中 Case 的使用介绍

Mysql 中 Case 的使用介绍

工作中经常需要写各种 sql 来统计线上的各种业务数据,使用 CASE 能让你的统计事半功倍,如果能用好它,不仅SQL 能解决的问题更广泛,写法也会漂亮地多,接下来让我们看看 CASE 的各种妙用吧,在开始之前我们简单学习一下 CASE 表达式的写法

CASE 表达式的两种写法

CASE 表示式有简单表达式和搜索表达式两种,如下

-- 简单 CASE 表达式
CASE sex
    WHEN '1' THEN '男'
    WHEN '2' THEN '女' ELSE '其他' 
END

-- 搜索 CASE 表达式
CASE WHEN sex = '1' THEN '男'
     WHEN sex = '2' THEN '女' ELSE '其他' 
END

需要注意的是每个WHEN子句都具有排他性,也就是说如果执行到某个 WHEN 子句为真,则剩余的 WHEN 子句不会执行,所以为了引起不必要的麻烦,WHEN 子句要注意条件的互斥性

CASE 的用法详解

知道了 CASE 的用法,接下来我们来举几个例子来看下 CASE 的几种妙用,首先让我们准备两张表(字段设计还有优化的空间,只是为了方便演示 CASE 的使用),用户表(customer) 和 订单表(order),一个用户可以有多个订单,所以用户与订单的关系是一对多的

这两个表的数据如下

customer 表

id

name

gender

district

vip_level

1

张三

杭州

1

2

李四

杭州

2

3

王五

海口

3

4

赵六

义乌

2

5

王五

三沙

2

order 表

id

customer_id

1

1

2

1

3

2

4

3

5

4

数据准备好了,现在重点来了,考虑以下问题,我们该怎么处理

1.统计浙江,海南的用户数普通写法: 写两个 sql 分别统计浙江,海南的订单数

-- 统计浙江用户数
SELECT COUNT(*) FROM customer WHERE district IN ('杭州','义乌')

-- 统计海南用户数
SELECT COUNT(*) FROM customer WHERE district IN ('海口', '三沙')

进阶用法:使用 CASE 来统计,一句 sql 搞定

SELECT CASE district
            when '义乌' then '浙江'
            when '杭州' then '浙江'
            when '海口' then '海南'
            when '三沙' then '海南'
            ELSE '其他' END AS  'province',
           COUNT(*)
FROM customer 
GROUP BY province

2.将 vip_ level 为 3 的更新成 2 ,将vip_level 为 2 的更新成 3如果说统计 「统计浙江,海南的用户数」可以用两个 sql 分别来统计的话,那这个更新 vip_level 的操作就必须要用CASE 来更新了,假设我们用上个例子的套路分别写两个 sql 来更新的话,看下会发生什么

-- 先将vip_level 为 3 的更新为 2
UPDATE customer SET vip_level=2 WHERE vip_level=3
-- 再将vip_level 为 2 的更新为 3
UPDATE customer SET vip_level=3 WHERE vip_level=2

以上两步确实将 vip_level 为 2 的更新为 3了,但 vip_level 为 3 的经过上面两步之后最终并没有变成 2(先变成 2 再变成 3),那我们看看如何用 CASE 来实现我们的需求

UPDATE customer
    SET vip_level CASE WHEN vip_level = 3 THEN 2
                       WHEN vip_level = 2 THEN 3
                       ELSE vip_level END

可以看到实现方式简洁明了,需要注意的是最后一步 「ELSE vip END」极为关键,如果不加这一句,则如果 vip_level 不为 2 或 3,会被更新成 NULL,这样就会把其他值的 vip_level 给清掉

总结

可以看到,使用 CASE 给我们带来了很大的便利,不仅逻辑上更为紧凑,而且相比于多条 sql 的执行,使用 「CASE WHEN」一行就能解决问题,方便了很多

本文分享自微信公众号 - 码海(seaofcode)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-10-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 刨根问底---一次 OOM 试验造成的电脑雪崩引发的思考

    在写「垃圾回收-实战篇」时,按书中的一个例子做了一次实验,我觉得涉及的知识点挺多的,所以单独拎出来与大家共享一下,相信大家看完肯定有收获。

    kunge
  • 震惊!线上四台机器同一时间全部 OOM,到底发生了什么?

    昨天晚上突然短信收到 APM (即 Application Performance Management 的简称,我们内部自己搭建了这样一套系统来对应用的性能、...

    kunge
  • Gradle 编译速度提升 70%!怎么做到的?

    之前我司每个 Java 应用部署到预发都要等待漫长的编译打包时间,非常地痛苦!大项目编译时间常常达到接近 10 分钟,生命短暂啊,人生有多少个 10 分钟可以等...

    kunge
  • Linux架构之HA配置

    简介 通过安装该Linux-HA软件,可以实现Linux双机系统的高可用性解决方案,实现双机系统的热备份,并能够做到双机之间的无缝切换,从而对外 提供稳定可靠...

    小小科
  • 想提高面试通过率?回答好这10个问题征服面试官

    之前UI黑客发表了一篇叫《面试了50多位UI设计师,我总结了这些求职技巧》的文章,在网上得到很多设计师认可,感谢各位支持。

    奔跑的小鹿
  • Qt信号与槽宏定义

    Qt君
  • 大数据技术之_29_MySQL 高級面试重点串讲_02

      MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。

    黑泽君
  • CIA Vault7泄露文档第五波:多平台入侵植入和管理控制工具HIVE

    最近,NSA和CIA的网络武器都被捅娄子了,4月14日,就在ShadowBroker公布第二批NSA网络大杀器的同一天,维基解密继续公布了Vault7系列名为H...

    FB客服
  • NDK开发之 Undefined Reference to Typeinfo

    最近给现在代码增加个功能,可以使用代理走向内网指定服务器,但是功能增加后一直编译不过,报错:"Undefined Reference to Typeinfo H...

    望天
  • [分布式学习]消息队列之rocketmq笔记

    mq有很多,近期买了《分布式消息中间件实践》这本书,学习关于mq的相关知识。mq大致有有4个功能:

    _淡定_

扫码关注云+社区

领取腾讯云代金券