CASE 表達式 (SQL CASE Expression)
CASE 表達式是 SQL 中用於執行條件邏輯的功能,類似於程式語言中的 if/then/else 或 switch 語句。它可以根據不同的條件返回不同的值,讓你在查詢中實現複雜的邏輯判斷。
CASE 語法 (Syntax)
CASE 表達式有兩種形式:
1. 簡單 CASE 表達式 (Simple CASE)
將一個表達式與一系列值進行比較:
CASE expression
WHEN value1 THEN result1
WHEN value2 THEN result2
...
ELSE default_result
END
2. 搜尋 CASE 表達式 (Searched CASE)
評估一系列布林條件:
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
...
ELSE default_result
END
💡 注意: 如果省略
ELSE子句且沒有任何WHEN條件匹配,CASE 表達式會返回NULL。
CASE 用法範例 (Example)
questionnaire 資料表 (問卷調查:您喜歡這個網站嗎?):
| Name | Answer |
|---|---|
| 張一 | 1 |
| 王二 | 2 |
| 李三 | 3 |
(1 = 喜歡, 2 = 不喜歡, 3 = 還OK)
使用簡單 CASE
SELECT Name,
CASE Answer
WHEN 1 THEN '喜歡'
WHEN 2 THEN '不喜歡'
WHEN 3 THEN '還OK'
ELSE '未回答'
END AS Answer_Text
FROM questionnaire;
使用搜尋 CASE
SELECT Name,
CASE
WHEN Answer = 1 THEN '喜歡'
WHEN Answer = 2 THEN '不喜歡'
WHEN Answer = 3 THEN '還OK'
ELSE '未回答'
END AS Answer_Text
FROM questionnaire;
結果:
| Name | Answer_Text |
|---|---|
| 張一 | 喜歡 |
| 王二 | 不喜歡 |
| 李三 | 還OK |
CASE 的進階應用
1. 在 SELECT 中分類資料
SELECT Name, Salary,
CASE
WHEN Salary >= 80000 THEN '高薪'
WHEN Salary >= 50000 THEN '中薪'
ELSE '低薪'
END AS Salary_Level
FROM employees;
2. 在 ORDER BY 中自訂排序
SELECT * FROM employees
ORDER BY
CASE Dept
WHEN '管理' THEN 1
WHEN '研發' THEN 2
WHEN '業務' THEN 3
ELSE 4
END;
3. 在 WHERE 中動態條件
SELECT * FROM products
WHERE
CASE
WHEN @filter_type = 'expensive' THEN Price > 1000
WHEN @filter_type = 'cheap' THEN Price <= 100
ELSE 1 = 1 -- 不篩選
END;
4. 搭配聚合函數進行條件計數
SELECT
COUNT(CASE WHEN Status = 'Active' THEN 1 END) AS Active_Count,
COUNT(CASE WHEN Status = 'Inactive' THEN 1 END) AS Inactive_Count,
COUNT(*) AS Total_Count
FROM users;
5. 搭配 SUM 進行條件加總
SELECT
Dept,
SUM(CASE WHEN Gender = 'M' THEN 1 ELSE 0 END) AS Male_Count,
SUM(CASE WHEN Gender = 'F' THEN 1 ELSE 0 END) AS Female_Count
FROM employees
GROUP BY Dept;
6. 實現 PIVOT 效果
使用 CASE 可以模擬 PIVOT 的行列轉換效果:
SELECT
Region,
SUM(CASE WHEN Product = 'LCD' THEN Amount ELSE 0 END) AS LCD_Sales,
SUM(CASE WHEN Product = 'CPU' THEN Amount ELSE 0 END) AS CPU_Sales
FROM sales
GROUP BY Region;
7. NULL 值處理
SELECT Name,
CASE
WHEN Phone IS NULL THEN '未提供'
ELSE Phone
END AS Phone
FROM customers;
💡 提示: 對於簡單的 NULL 替換,也可以使用
COALESCE或ISNULL/IFNULL函數。
CASE vs IF()
IF()函數 是 MySQL 特有的,只能處理簡單的二元條件。CASE是標準 SQL,所有主流資料庫都支援,且可以處理多重條件。
-- MySQL IF():只能處理真/假兩種情況
SELECT IF(Stock > 0, '有庫存', '已售完') AS Status FROM products;
-- CASE:可以處理多重條件
SELECT CASE
WHEN Stock > 100 THEN '充足'
WHEN Stock > 0 THEN '偏低'
ELSE '已售完'
END AS Status
FROM products;
💡 建議: 為了跨資料庫相容性和更好的可讀性,建議優先使用
CASE表達式。
CASE 的執行順序
CASE 表達式會按照 WHEN 子句的順序依次評估,一旦找到匹配的條件就會停止並返回對應的結果。因此,條件的順序很重要:
-- 正確:先檢查更嚴格的條件
CASE
WHEN Score >= 90 THEN 'A'
WHEN Score >= 80 THEN 'B'
WHEN Score >= 60 THEN 'C'
ELSE 'F'
END
-- 錯誤:所有 >= 60 的都會匹配第一個條件
CASE
WHEN Score >= 60 THEN 'C' -- Score = 95 也會匹配這裡
WHEN Score >= 80 THEN 'B'
WHEN Score >= 90 THEN 'A'
ELSE 'F'
END