SQL進階教程(一)——CASE表達式

SQL進階教程之CASE表達式

在掌握了基礎的標準SQL語法後,可做一些簡單的SQL練習題加深記憶和鞏固基礎知識。然而,SQL基礎教程僅僅是幫助零基礎的同學入門,要想在面試或工作中用好SQL,需進一步學習進階教程,從而從初級邁向中級。在這個階段我參考的書仍然是MICK先生所著的==《SQL進階教程》==,這本書主要以案例爲主,通過不同的案例幫助讀者快速瞭解不同情況下SQL語句的使用策略,對於時間比較緊張想要快速提高的同學非常適合。關於CASE表達式的應用本文從以下幾個方面進行介紹:

  1. 使用CASE表達式時需注意的點
  2. CASE表達式的具體應用場景

CASE表達式:

CASE  WHEN  <表達式>   THEN  <表達式>  
      ELSE   <表達式>
      END

1.使用CASE表達式需注意的點

  1. 各個分支<表達式>返回的數據類型要統一;
  2. CASE寫完後不能丟了END
  3. ELSE可省略但不建議省,沒有值時可寫 ELSE NULL。

2.CASE表達式應用的具體場景

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)。
(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


  1. 《SQL進階教程》,[日] MICK/著,吳炎昌/譯 ↩︎

發佈了9 篇原創文章 · 獲贊 17 · 訪問量 997
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章