如果你已經知道 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 就是你讓查詢變清楚的利器。
GO TO FULL VERSION