新手用 WHERE 子句和 HAVING 子句进行条件分支,高手用 SELECT 子句进行条件 分支。
1.1 基础使用
CASE 表达式是不依赖于具体 数据库的技术,所以可以提高 SQL 代码的可移植性。
1 | CREATE TABLE `users` ( |
如果 CASE 表达式里没有明确指定 ELSE 子句, 执行结果会被默认地处理成ELSE NULL。所以一定要写ELSE。
1.2 select 不同条件
1 | /* 用一条SQL语句进行不同条件的统计 */ |
这个技巧可贵的地方在于,它能将 SQL 的查询结果转换为二维表的格式。
如果只是简单地用 GROUP BY 进行聚合,那么查询后必须通过程序将结果的格式转换一下,才能使之成为交叉表。
1.3 update 调换值
1 | /* 用CASE表达式调换主键值 */ |
1.4 强大表达能力
在 CASE 表达式里,我们可以使用 BETWEEN、LIKE 和 <、 > 等 便利的谓词组合,以及能嵌套子查询的 IN 和 EXISTS 谓词。因此,CASE 表达式具有非常强大的表达能力。
作为表达式,CASE 表达式在执行时会被判定为一个固定值,因此它 可以写在聚合函数内部;也正因为它是表达式,所以还可以写在 SELECE 子句、GROUP BY 子句、WHERE 子句、ORDER BY 子句里。简单点说,在能 写列名和常量的地方,通常都可以写 CASE 表达式。
1.5 练习
- 从多列数据里选出最大值该怎么做呢
1 | SELECT `key`, CASE WHEN x > y THEN x ELSE (CASE WHEN y > z THEN y ELSE z END) END greatest FROM Greatests |
用 ORDER BY 生成“排序”列, 使得结果按照 B-A-D-C 这样的指定顺 序进行排列。
1
2
3
4
5
6SELECT `key` FROM Greatests ORDER BY CASE `key`
WHEN 'B' THEN 1
WHEN 'A' THEN 2
WHEN 'D' THEN 3
WHEN 'C' THEN 4
ELSE NULL END;转换行列 (1.2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14SELECT CASE WHEN sex = 1 THEN '男' ELSE '女' END 性别,
SUM(population) AS total,
SUM(CASE WHEN pref_name = '德岛' THEN population ELSE 0 END) AS 德岛,
SUM(CASE WHEN pref_name = '香川' THEN population ELSE 0 END) AS 香川,
SUM(CASE WHEN pref_name = '爱媛' THEN population ELSE 0 END) AS 爱媛,
SUM(CASE WHEN pref_name = '高知' THEN population ELSE 0 END) AS 高知,
SUM(CASE WHEN pref_name IN ('德岛', '香川', '爱媛', '高知') THEN population ELSE 0 END) AS 四国
FROM PopTbl2
GROUP BY sex;
/*
男 855 60 100 100 100 360
女 845 40 100 50 100 290
*/
1.6 总结
- 在 GROUP BY 子句里使用 CASE 表达式,可以灵活地选择作为聚合 的单位的编号或等级。这一点在进行非定制化统计时能发挥巨大的威力。 2. 在聚合函数中使用 CASE 表达式,可以轻松地将行结构的数据转换
成列结构的数据。 - 相反,聚合函数也可以嵌套进 CASE 表达式里使用。
- 相比依赖于具体数据库的函数,CASE 表达式有更强大的表达能力
和更好的可移植性。 - 正因为 CASE 表达式是一种表达式而不是语句,才有了这诸多优点。