《SQL进阶教程》

第一章 神奇的SQL之CASE

CASE 表达式

概述
利用CASE 表达式来进行分支判断,有两种CASE表达式:简单表达式(simple case expresssion )和搜索表达式(searched case expression)。

简单表达式 vs 搜索表达式

1
2
3
4
5
6
7
8
9
10
11
12
-- 简单CASE 表达式
CASE sex WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE '其他' END



-- 搜索CASE 表达式
CASE WHEN sex = '1' THEN '男'
WHEN sex = '2' THEN '女'
ELSE '其他'
END

使用CASE 的注意点:

1.统一各分支返回的数据类型,CASE 各个分支的返回值的类型是需要一直的

2.不要忘了写END,很有可能出现问题

3.养成写ELSE 的习惯

使用CHECK约束
1
2
3
4
5
CONSTRAINT check_salary CHECK          
( CASE WHEN sex = '2'
THEN CASE WHEN salary <= 200000
THEN 1 ELSE 0 END
ELSE 1 END = 1 )
在UPDATE语句中进行条件分支
1
2
3
4
5
6
7
8

-- 用CASE 表达式写正确的更新操作
UPDATE Salaries
SET salary = CASE WHEN salary >= 300000
THEN salary * 0.9
WHEN salary >= 250000 AND salary < 280000
THEN salary * 1.2
ELSE salary END; --这里的Else 很重要 ,否则,不在CASE范围内的数据,就被置为空
表之间的数据匹配

和DECODE 函数相比,CASE表达式中一大优势是能够判断表达式,可以在CASE 中使用谓词组合。

1
2
3
4
5
6
7
8

SELECT CM.course_name,
CASE WHEN EXISTS
(SELECT course_id FROM OpenCourses OC WHERE month = 200706 AND OC.course_id = CM.course_id) THEN '○' ELSE '×' END AS "6 月", CASE WHEN EXISTS
(SELECT course_id FROM OpenCourses OC WHERE month = 200707 AND OC.course_id = CM.course_id) THEN '○'
ELSE '×' END AS "7 月",
CASE WHEN EXISTS
(SELECT course_id FROM OpenCourses OC WHERE month = 200708 AND OC.course_id = CM.course_id) THEN '○' ELSE '×' END AS "8 月" FROM CourseMaster CM;
CASE 也可以使用聚合函数
1
2
3
4
5
6
7
8
9

SELECT std_id,
CASE WHEN COUNT(*) = 1 -- 只加入了一个社团的学生
THEN MAX(club_id)
ELSE MAX(CASE WHEN main_club_flg = 'Y'
THEN club_id
ELSE NULL END)
END AS main_club
FROM StudentClub GROUP BY std_id;

本节要点:

  1. 在 GROUP BY 子句里使用 CASE 表达式,可以灵活地选择作为聚 合的单位的编号或等级。这一点在进行非定制化统计时能发挥巨 大的威力。

  2. 在聚合函数中使用 CASE 表达式,可以轻松地将行结构的数据转 换成列结构的数据。

  3. 相反,聚合函数也可以嵌套进 CASE 表达式里使用。

  4. 相比依赖于具体数据库的函数,CASE 表达式有更强大的表达能 力和更好的可移植性。

  5. 正因为 CASE 表达式是一种表达式而不是语句,才有了这诸多优 点

练习题: