CodeGym /課程 /SQL SELF /條件表達式: CASE <表達式> WHEN ... THEN ... ELSE ......

條件表達式: CASE <表達式> WHEN ... THEN ... ELSE ... END

SQL SELF
等級 10, 課堂 1
開放

如果你已經知道 CASE,那你應該知道它可以直接把邏輯寫進查詢裡。但不是每個人都知道 CASE 有兩種寫法。如果是 CASE WHEN ... — 這就像 if-else 條件判斷,而簡單 CASE — 就像其他語言裡的 switch-case:它會把一個表達式跟多個值比對,然後執行對應的區塊。

當你要比對一個欄位跟固定值時,這種寫法看起來更簡潔、也更直觀。

簡單 CASE 的語法

CASE expression
    WHEN value1 THEN result1
    WHEN value2 THEN result2
    ...
    ELSE default_result
END

很簡單啦:

  • expression — 這是你要比對的表達式或欄位,會跟 value1、value2 等等去比。
  • THEN 指定如果符合要回傳什麼。
  • ELSE — 如果都沒中要回傳什麼(可以省略,但最好還是寫)。

範例:學生的成績

假設有個 students 表,裡面有個 grade 欄位,存的是 2 到 5 的整數。我們想要顯示成績的文字說明。

SELECT
    name,
    grade,
    CASE grade
        WHEN 5 THEN '優秀'
        WHEN 4 THEN '良好'
        WHEN 3 THEN '及格'
        WHEN 2 THEN '不及格'
        ELSE '未知'
    END AS 成績_文字
FROM students;

這裡 CASE 會把 grade 欄位的值跟 2、3、4、5 這些固定值比對。

範例:依代碼顯示商品分類

在 products 表裡有個 category_code 欄位,裡面存的是像 'el'、'frn'、'bks' 這種短代碼。我們想要顯示看得懂的分類名稱。

SELECT
    product_name,
    category_code,
    CASE category_code
        WHEN 'el' THEN '電子產品'
        WHEN 'frn' THEN '家具'
        WHEN 'bks' THEN '書籍'
        ELSE '其他'
    END AS category_name
FROM products;

這招特別適合把「代碼」轉成「人話」來顯示。

範例:月份名稱

有時候你會想根據月份數字顯示月份名稱:

SELECT
    EXTRACT(MONTH FROM order_date) AS month_number,
    CASE EXTRACT(MONTH FROM order_date)
        WHEN 1 THEN '一月'
        WHEN 2 THEN '二月'
        WHEN 3 THEN '三月'
        WHEN 4 THEN '四月'
        WHEN 5 THEN '五月'
        WHEN 6 THEN '六月'
        WHEN 7 THEN '七月'
        WHEN 8 THEN '八月'
        WHEN 9 THEN '九月'
        WHEN 10 THEN '十月'
        WHEN 11 THEN '十一月'
        WHEN 12 THEN '十二月'
        ELSE '未知'
    END AS month_name
FROM orders;

這裡簡單 CASE 讓原本只有 1~12 的數字變得一目了然。

簡單 CASE 處理 NULL

要注意,如果你拿 NULL 來比對,結果會是 NULL,因為 NULL = NULL — 不是 true,而是未知。

NULL 範例:

SELECT
    user_id,
    status,
    CASE status
        WHEN 'active' THEN '啟用'
        WHEN 'blocked' THEN '封鎖'
        WHEN NULL THEN '沒有狀態'  -- 不會生效!
        ELSE '未知'
    END AS user_state
FROM users;

不要用 WHEN NULL,要嘛用 ELSE,要嘛直接用搜尋型 CASE(我們上次講過):

CASE
    WHEN status IS NULL THEN '沒有狀態'
    ...

跟搜尋型 CASE 的比較

特點 簡單 CASE 搜尋型 CASE
比對固定值 ✅ 很方便 ❌ 不適合
條件彈性(>, IS NULL) ❌ 不行 ✅ 可以
程式語言對應 switch-case if-else

實用案例

範例:申請單狀態視覺化

request_id status
101 new
102 in_progress
103 done
104 cancelled
105 NULL
SELECT
    request_id,
    CASE status
        WHEN 'new' THEN '🟡 新的'
        WHEN 'in_progress' THEN '🔵 處理中'
        WHEN 'done' THEN '🟢 完成'
        ELSE '⚪ 未知'
    END AS status_label
FROM requests;
request_id status_label
101 🟡 新的
102 🔵 處理中
103 🟢 完成
104 ⚪ 未知
105 ⚪ 未知

這裡 CASE 就像翻譯機:把技術狀態變成大家都懂(還有點可愛)的標籤。如果狀態未知或 NULL — 使用者就會看到 ⚪「未知」。

範例:報表分組

employee_id name department
1 Alex Lin HR
2 Maria Chi IT
3 Anna Song IT
4 Otto Art FIN
5 Jane Doe HR
6 Max Gray SALES
7 Zoe Black IT
8 Tom Brown FIN
9 Liam Park NULL
10 Eva Gold HR
SELECT
    CASE department
        WHEN 'HR' THEN '人資'
        WHEN 'IT' THEN '技術'
        WHEN 'FIN' THEN '財務'
        ELSE '其他'
    END AS dept_name,
    COUNT(*) AS staff_count
FROM employees
GROUP BY
    CASE department
        WHEN 'HR' THEN '人資'
        WHEN 'IT' THEN '技術'
        WHEN 'FIN' THEN '財務'
        ELSE '其他'
    END;

結果:

dept_name staff_count
人資 3
技術 3
財務 2
其他 2

這裡發生了什麼:

  • HR 部門的員工會被歸到「人資」。
  • IT 就是「技術」。
  • FIN 就是「財務」。
  • 其他的(像 SALES 跟 NULL)都歸到「其他」。這種做法很適合做出友善又好懂的報表。

常見錯誤

  • 忘記寫 ELSE → 如果沒對到任何值就會拿到 NULL。
  • 跟 NULL 比對 → 不會動,要用 IS NULL 跟搜尋型 CASE。
  • 比對不同型別 → 例如 CASE grade WHEN '5',但 grade 是數字型。

簡單 CASE — 就是你要比對一個值跟一堆可能值時的好工具。它簡潔、好讀,特別適合做文字分類、視覺化、代碼轉換還有分組。

如果你要判斷範圍、NULL 或更複雜的條件 — 就用搜尋型 CASE。SQL 喜歡清楚明白。而 CASE 就是你讓查詢變清楚的利器。

2
任務
SQL SELF, 等級 10, 課堂 1
上鎖
為分數賦予文字描述
為分數賦予文字描述
2
任務
SQL SELF, 等級 10, 課堂 1
上鎖
商品分類比較
商品分類比較
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION