mysql 中 case when 的使用

126 阅读2分钟

klarin-steffens-R6aGTlvCCWw-unsplash.jpg 本文正在参加「技术专题19期 漫谈数据库技术」活动

问题分析

最近遇到一个问题:

yearamountnum
199111.1
199121.2
199131.3
199212.1
199222.2
199232.3

把上面表格的数据查询成:

yearm1m2m3
19911.11.21.3
19922.12.22.3

看到这样的需求,首先想到的是用 case 去统计以及用 group by 来分组

第一版 sql 代码:

SELECT
	`year`,
	(CASE WHEN amount = 1 THEN num END) AS m1,
	(CASE WHEN amount = 2 THEN num END) AS m2,
	(CASE WHEN amount = 3 THEN num END) AS m3
FROM
	test
GROUP BY
	`year`

查询出来的结果有点不如人意:

yearm1m2m3
19911.1
19922.1

这么说明了分组之后只显示到第一行数据,那么我们去掉分组看看:

SELECT
    `year`,
    (CASE WHEN amount = 1 THEN num END) AS n1,
    (CASE WHEN amount = 2 THEN num END) AS n2,
    (CASE WHEN amount = 3 THEN num END) AS n3
FROM
    test

得到的结果是:

yearm1m2m3
19911.100
199101.20
1991001.3
19922.100
199202.20
1992002.3

有点像我们想要的了,只是没有分组以及去掉空值

而且我们可以看出,在分组的情况下 m1, m2, m3 的值都是一个最大值来的

所以我们可以用一个子查询来查询上面的结果集中分组的最大值 最终版 sql

SELECT
	`year`,
	MAX(n1) AS m1,
	MAX(n2) AS m2,
	MAX(n3) AS m3
FROM
(
    SELECT
        `year`,
        (CASE WHEN amount = 1 THEN num END) AS n1,
        (CASE WHEN amount = 2 THEN num END) AS n2,
        (CASE WHEN amount = 3 THEN num END) AS n3
    FROM
        test
) AS a
GROUP BY
	`year`

最终可以得到我们想要的结果:

yearm1m2m3
19911.11.21.3
19922.12.22.3

case when 语法

第一种用法:

CASE value
    WHEN compare_value THEN result
    [WHEN compare_value THEN result ...]
    [ELSE result]
END

第二种用法:

CASE
    WHEN condition THEN result
    [WHEN condition THEN result ...]
    [ELSE result]
END

两种用法的区别:

第一种CASE语法返回的是第一个value=compare_valuetrue的分支的结果。

第二种CASE语法返回的是第一个conditiontrue的分支的结果。

case when的使用场景

  • 根据条件转换字段含义
SELECT
    name '姓名',
    age '年龄',
    CASE
        WHEN age < 18 THEN '少年'
        WHEN age < 30 THEN '青年'
        WHEN age >= 30 AND age < 50 THEN '中年'
        ELSE '老年'
    END '年龄段'
FROM
    user_info;
  • 输出多个指标

老师要统计班中,有多少男同学,多少女同学,并统计男同学中有几人及格,女同学中有几人及格,要求用一个SQL输出结果。

  • 行转列

就正如本文上面例子所示

  • SQL优化

case when 性能调优

最后

如果文章可以给你带来一丝收获,请举起你的手指,给我来个一键三连吧!

参考文章

juejin.cn/post/697104…

my.oschina.net/u/1187675/b…

blog.csdn.net/rongtaoup/a…