CASE 表達式 (SQL CASE Expression)

CASE 表達式是 SQL 中用於執行條件邏輯的功能,類似於程式語言中的 if/then/elseswitch 語句。它可以根據不同的條件返回不同的值,讓你在查詢中實現複雜的邏輯判斷。

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 資料表 (問卷調查:您喜歡這個網站嗎?):

NameAnswer
張一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;

結果:

NameAnswer_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 替換,也可以使用 COALESCEISNULL/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

相關主題