如下这个表TEST
:
category | commdity | price
------------+------------+-------
衣服 | T恤 | 1000
办公用品 | 打孔器 | 500
厨房用具 | 菜刀 | 3000
厨房用具 | 高压锅 | 6800
厨房用具 | 叉子 | 500
厨房用具 | 擦菜板 | 880
办公用品 | 圆珠笔 | 100
衣服 | 运动T恤 | 4000
如果我想把商品按照1000元以下,1000-3000, 3000 以上分为三个档次显示出来,正确的语句是:
SELECT SUM (CASE WHEN price <= 1000 THEN 1 ELSE 0 END)AS low,
SUM (CASE WHEN price BETWEEN 1001 AND 3000 THEN 1 ELSE 0 END)AS mid,
SUM (CASE WHEN price > 3000 THEN 1 ELSE 0 END)AS high FROM TEST;
得出结果
low | mid | high
-----+-----+------
5 | 1 | 2
当把上述语句的sum
换成count
时,得出结果:
low | mid | high
-----+-----+------
8 | 8 | 8
如果只是用列来显示,SELECT COUNT(price) FROM TEST WHERE price <= 1000
可以得出正确的结果:
low
-----
5
所以用sum
的结果是对的。
原因是什么呢?
三个case
语句效果相同,其实就是类似于增加一个字段,这个字段,满足条件的为1
,不满足的是0
,这样sum
的效果,就是将所有的1
加起来,也就是所有满足条件的记录个数。
而count
,会不管是1
还是0
,都会统计,这样怎么算都是总条目数8个。
实现分组统计
如,我希望统计users
表中每个创建者创建的男性、女性、无性别的用户总数(数据表中有一个字段creator_id
,表示创建者的ID
),语句如下:
select u.creator_id 创建者ID,
sum( case u.sex when 1 then 1 else 0 end) 男性,
sum( case u.sex when 2 then 1 else 0 end) 女性,
sum( case when u.sex<>1 and u.sex<>2 then 1 else 0 end) 性别为空
from users u group by u.creator_id;
Oracle CASE WHEN 用法介绍
1. CASE WHEN
表达式有两种形式
--简单Case函数
CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE '其他' END
--Case搜索函数
CASE
WHEN sex = '1' THEN '男'
WHEN sex = '2' THEN '女'
ELSE '其他' END
2. CASE WHEN
在语句中不同位置的用法
2.1 SELECT CASE WHEN
用法
SELECT grade, COUNT (CASE WHEN sex = 1 THEN 1 /*sex 1为男生,2位女生*/
ELSE NULL
END) 男生数,
COUNT (CASE WHEN sex = 2 THEN 1
ELSE NULL
END) 女生数
FROM students GROUP BY grade;
2.3 WHERE CASE WHEN
用法
SELECT T2.*, T1.*
FROM T1, T2
WHERE (CASE WHEN T2.COMPARE_TYPE = 'A' AND
T1.SOME_TYPE LIKE 'NOTHING%'
THEN 1
WHEN T2.COMPARE_TYPE != 'A' AND
T1.SOME_TYPE NOT LIKE 'NOTHING%'
THEN 1
ELSE 0
END) = 1
2.4 GROUP BY CASE WHEN
用法
SELECT
CASE WHEN salary <= 500 THEN '1'
WHEN salary > 500 AND salary <= 600 THEN '2'
WHEN salary > 600 AND salary <= 800 THEN '3'
WHEN salary > 800 AND salary <= 1000 THEN '4'
ELSE NULL END salary_class, -- 别名命名
COUNT(*)
FROM Table_A
GROUP BY
CASE WHEN salary <= 500 THEN '1'
WHEN salary > 500 AND salary <= 600 THEN '2'
WHEN salary > 600 AND salary <= 800 THEN '3'
WHEN salary > 800 AND salary <= 1000 THEN '4'
ELSE NULL END;
3.关于IF-THEN-ELSE
的其他实现
3.1 DECODE()
函数
select decode(sex, 'M', 'Male', 'F', 'Female', 'Unknown')
from employees;
貌似只有Oracle
提供该函数,而且不支持ANSI SQL
,语法上也没CASE WHEN
清晰,个人不推荐使用。
3.2 在WHERE中特殊实现
SELECT T2.*, T1.*
FROM T1, T2
WHERE (T2.COMPARE_TYPE = 'A' AND T1.SOME_TYPE LIKE 'NOTHING%')
OR
(T2.COMPARE_TYPE != 'A' AND T1.SOME_TYPE NOT LIKE 'NOTHING%')
这种方法也是在特殊情况下使用,要多注意逻辑,不要弄错。
oracle
中when then else
与decode
的两种用法,null
(
CASE
WHEN T2.BLESSNUM IS NULL
THEN 0
ELSE T2.BLESSNUM
END) AS BLESSNUM
或者
ENCODE( T2.BLESSNUM, NULL,0,T2.BLESSNUM) AS BLESSNUM
ENCODE(t.status,'C','审批通过','P','审批中','N','未提交','D','审批未通过')as status
两种用法在没有涉及到的结果通通为null
,判断一个结果值是否为空用is null
或者is not null
而不是=null
或者==null