SQL進階教程之CASE表達式
在掌握了基礎的標準SQL語法後,可做一些簡單的SQL練習題加深記憶和鞏固基礎知識。然而,SQL基礎教程僅僅是幫助零基礎的同學入門,要想在面試或工作中用好SQL,需進一步學習進階教程,從而從初級邁向中級。在這個階段我參考的書仍然是MICK先生所著的==《SQL進階教程》==,這本書主要以案例爲主,通過不同的案例幫助讀者快速瞭解不同情況下SQL語句的使用策略,對於時間比較緊張想要快速提高的同學非常適合。關於CASE表達式的應用本文從以下幾個方面進行介紹:
- 使用CASE表達式時需注意的點
- CASE表達式的具體應用場景
CASE表達式:
CASE WHEN <表達式> THEN <表達式>
ELSE <表達式>
END
1.使用CASE表達式需注意的點
- 各個分支
<表達式>
返回的數據類型要統一; - CASE寫完後不能丟了END
- ELSE可省略但不建議省,沒有值時可寫 ELSE NULL。
2.CASE表達式應用的具體場景
(1)行列轉換
行列轉換是將行所展現的結果轉到列中進行展示。
SELECT pref_name,
SUM(CASE WHEN sex = '1' THEN population ELSE 0 END) AS cnt_m --男性人口
SUM(CASE WHEN sex = '2' THEN population ELSE 0 END) AS cnt_m --女性人口
FROM <表名>
GROUP BY pref_name;
(2)已有數據重分組
SELECT CASE pref_name
WHEN '德島' THEN '四國'
WHEN '香川' THEN '四國'
WHEN '愛媛' THEN '四國'
WHEN '高知' THEN '四國'
WHEN '福岡' THEN '九州'
WHEN '佐賀' THEN '九州'
WHEN '長崎' THEN '九州'
ELSE '其他' END AS district,
SUM(population)
FROM PopTbl
GROUP BY CASE pref_name
WHEN '德島' THEN '四國'
WHEN '香川' THEN '四國'
WHEN '愛媛' THEN '四國'
WHEN '高知' THEN '四國'
WHEN '福岡' THEN '九州'
WHEN '佐賀' THEN '九州'
WHEN '長崎' THEN '九州'
ELSE '其他' END;
注:PostgreSQL & MySQL中可將GROUP BY 子句替換爲別名,即GROUP BY district
;其他數據庫不可。
(3)與約束的結合使用
這類主要針對“蘊含式”的問題,比如女性的工作時長不能超過8小時,先要判斷員工是否爲女性,其次判斷工作市場是否爲8小時,這裏要注意和邏輯與進行區分。
CONSTRAINT check_worktime CHECK
( CASE WHEN sex = '2'
THEN CASE WHEN worktime <= 8
THEN 1 ELSE 0 END
ELSE 1 END = 1 )
(4)在UPDATE語句裏的條件分支
這類主要用於同時更新多個值的情況。
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;
(5)表之間的數據匹配
主要用於產生交叉表。即下圖中由(1)(2)得到(3)。
使用IN的情況
SELECT course_name,
CASE WHEN course_id IN (SELECT course_id FROM OpenCourses WHERE month = 200706)
THEN 'O'ELSE 'x' END AS "6月",
CASE WHEN course_id IN (SELECT course_id FROM OpenCourses WHERE month = 200707)
THEN 'O'ELSE 'x' END AS "7月",
CASE WHEN course_id IN (SELECT course_id FROM OpenCourses WHERE month = 200708)
THEN 'O'ELSE 'x' END AS "8月"
FROM CourseMaster;
使用EXISTS的情況
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;
(6)針對聚合結果的條件分支
要求:01獲取只加入了一個社團的學生的社團 ID;02. 獲取加入了多個社團的學生的主社團 ID。
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 mian_club
FROM StudentClub
GROUP BY std_id;
以上就是CASE表達式可應用的具體場景。各類場景的案例均來源於《SQL進階教程》。1
《SQL進階教程》,[日] MICK/著,吳炎昌/譯 ↩︎