SQL进阶教程第一章-----------------CASE表达式
CASE表达式是从SQL-92标准开始被引入,但是很多人并不使用它,或者只是使用它的简略版函数,例如Oracle中的DECODE,MySQL中的IF函数等。然而SQL中使用CASE表达式能够解决的问题十分广泛,而且CASE表达式不依赖于具体数据库,可以提高SQL代码的可移植性。
CASE表达式有简单CASE表达式和搜索CASE表达式两种写法。
1.简单CASE表达式
CASE sex WHEN '1' THEN '女' WHEN '0' THEN '男' ELSE '其他' END
2.搜索case表达式
CASE WHEN sex = '1' THEN '女' WHEN sex='0' THEN '男' ELSE '其他' END
搜索CASE表达式相较于简单CASE表达式的优点是搜索CASE表达式能够使用更为复杂的搜索条件。
注意点:
1.只要发现为真的WHEN子句,CASE表达式的真假值判断就会中止,剩余的WHEN子句会被忽略,所以使用WHEN子句时要注意条件的排他性;
eg:,下面的CASE语句如果col值为A,则只会返回1,不会返回2;
CASE WHEN col IN ('A','B') THEN '1' WHEN col IN ('A) THEN '2' ELSE '3' END
2. 统一各分支返回的数据类型;
3. 不要忘记写END;
4. 不要忘记写ELSE. 不写ELSE语句,CASE表达式的执行结果是NULL, 但是即使是在结果可以为NULL的情况下也要写上ELSE子句,以防止结果不对。
CASE表达式应用一:将已有编号方式转换为新的方式并统计
在进行非定制化统计时,我们通常会遇到将已有编号方式转换为另一种便于分析的方式并进行统计的需求。
例如:
我们需要统计如下表1中的内容,并得出表2的所示结果。
在统计结果这张表中,“四国”对应的是统计结果表中的“德岛、香川、爱媛、高知”,“九州”对应的是“福冈、佐贺、长崎”,不得不说日本真是一个自大的民族,一个岛国非要取这些九州四国的名字。
SELECT CASE WHEN pref_name IN ('德岛','香川','爱媛','高知') THEN '四国' WHEN pref_name IN ('福冈','佐贺','长崎') THEN '九州' ELSE '其他' END AS '地区', SUM(population) AS '人口'FROM PopTb1 GROUP BY CASE WHEN pref_name IN ('德岛','香川','爱媛','高知') THEN '四国' WHEN pref_name IN ('福冈','佐贺','长崎') THEN '九州' ELSE '其他' END;
这里的关键在于将SELECT 子句里面的CASE表达式复制到GROUP BY子句!!
将数值按照数量的级别进行分类统计,例如,要按照人口数量等级查询都道府县个数:
人口数量小于100------01级
大于等于100,小于200--------02级
大于等于200,小于300---------03级
大于等于300-----------04级
统计各个等级的县的数目
SELECT CASE WHEN population < 100 THEN '01' WHEN population >= 100 AND population < 200 THEN '02' WHEN population >= 200 AND population < 300 THEN '03' WHEN population >= 300 THEN '04' ELSE NULL END AS pop_class, COUNT(*) AS cnt FROM PopTb1 GROUP BY CASE WHEN population < 100 THEN '01' WHEN population >= 100 AND population < 200 THEN '02' WHEN population >= 200 AND population < 300 THEN '03' WHEN population >= 300 THEN '04' ELSE NULL END;
用一条SQL语句进行不同条件的统计
进行不同条件的统计是CASE表达式的主要用法之一,
例如,我们需要往存储各县人口数量的表PopTb1里添加上“性别”列,然后求按性别、县名汇总的人数。
实现方式:
SELECT pref_name, SUM(CASE WHEN sex = '1' THEN population ELSE 0 END) AS '男', SUM(CASE WHEN sex = '0' THEN population ELSE 0 END) AS '女' FROM PopTb2 GROUP BY pref_name
感觉很巧妙,除了SUM、COUNT AVG等聚合函数也都可以进行此类统计。如果用一句话来形容这个技巧,可以这样说:
新手用WHERE子句进行条件分支,高手用SELECT子句进行条件分支!!