美文网首页IT 森林
MySql 中 Case 的使用

MySql 中 Case 的使用

作者: 谢kun | 来源:发表于2019-10-11 22:31 被阅读0次

    工作中经常需要写各种 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),一个用户可以有多个订单,所以用户与订单的关系是一对多的

    a5ecb01187ea32bcded445ce0c105c04.png

    这两个表的数据如下

    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 给更新成 null

    总结

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

    公众号: 码农蜕变之路,定期分享各种 IT 技能,欢迎交流
    个人微信:geekoftaste,期待一起交流!


    image

    相关文章

      网友评论

        本文标题:MySql 中 Case 的使用

        本文链接:https://www.haomeiwen.com/subject/soffmctx.html