萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL CASE WHEN 條件判斷完全指南:語法變體、資料類型推斷與實戰模式

CASE 表達式是 SQL 中實現條件邏輯的核心工具,支援簡單/搜尋兩種語法,返回類型依語境自動推斷。本文系統梳理語法細節、類型規則與實戰模式。

兩種核心語法形式

1. 簡單 CASE(Simple Case) - 值比較模式

CASE `運算式`
    WHEN `比較值1` THEN `結果1`
    WHEN `比較值2` THEN `結果2`
    ...
    ELSE `預設結果`
END

類似 switch-case,運算式 與各 WHEN 值做等值比較。

2. 搜尋 CASE(Searched Case) - 條件判斷模式

CASE
    WHEN `條件1` THEN `結果1`
    WHEN `條件2` THEN `結果2`
    ...
    ELSE `預設結果`
END

每個 WHEN 後接完整布林表達式,靈活度最高,支援範圍、複合條件。

返回類型自動推斷規則

  • 所有 THEN/ELSE 結果類型一致 → 直接返回該類型
  • 類型不一致 → 依優先級隱性轉換:數值 > 日期/時間 > 字串
  • 字串語境 → 返回 VARCHAR/TEXT
  • 數值語境 → 返回 DECIMAL/DOUBLE/BIGINT
  • 若有 NULL 結果 → 返回類型可為 NULL

實戰範例集錦

基礎條件分支

SELECT CASE 
    WHEN 10*2 = 30 THEN '30 correct'
    WHEN 10*2 = 40 THEN '40 correct'
    ELSE 'Should be 10*2=20'
END AS `result`; -- 輸出: 'Should be 10*2=20'

簡單 CASE 等值匹配

SELECT CASE 10*2
    WHEN 20 THEN '20 correct'
    WHEN 30 THEN '30 correct'
    WHEN 40 THEN '40 correct'
END AS `result`; -- 輸出: '20 correct'

影片分級策略映射(經典業務場景)

SELECT 
    `Name`,
    `RatingID` AS `Rating`,
    CASE `RatingID`
        WHEN 'R' THEN 'Under 17 requires an adult.'
        WHEN 'X' THEN 'No one 17 and under.'
        WHEN 'NR' THEN 'Use discretion when renting.'
        ELSE 'OK to rent to minors.'
    END AS `Policy`
FROM `DVDs`
ORDER BY `Name`;

輸出結果:

NameRatingPolicy
AfricaPGOK to rent to minors.
AmadeusPGOK to rent to minors.
ChristmasNRUse discretion when renting.
DocGOK to rent to minors.
FalconNRUse discretion when renting.
MashRUnder 17 requires an adult.
ShowNRUse discretion when renting.
ViewNRUse discretion when renting.

進階:動態排序、條件聚合、NULL 處理

-- 動態排序:依參數決定排序欄位
SELECT * FROM `products`
ORDER BY CASE @sort_by
    WHEN 'price_asc'  THEN `price`
    WHEN 'price_desc' THEN -`price`
    WHEN 'name'       THEN `name`
    ELSE `created_at`
END;

-- 條件聚合:單次掃描統計多維度指標
SELECT 
    COUNT(*) AS `total`,
    SUM(CASE WHEN `status` = 'paid' THEN 1 ELSE 0 END) AS `paid_count`,
    SUM(CASE WHEN `amount` > 1000 THEN 1 ELSE 0 END) AS `large_order_count`,
    AVG(CASE WHEN `type` = 'vip' THEN `amount` END) AS `vip_avg_amount`
FROM `orders`;

-- NULL 安全比較
SELECT CASE 
    WHEN `col` IS NULL THEN 'missing'
    WHEN `col` = '' THEN 'empty'
    ELSE `col`
END FROM `t1`;

常見陷阱與最佳實踐

  1. 型別一致性:所有分支結果盡量保持相同類型,避免隱性轉換導致索引失效或精度損失
  2. ELSE 子句:習慣性加上 ELSE NULL 或預設值,避免隱性返回 NULL 導致應用層異常
  3. 短路求值:MySQL 按順序評估 WHEN,滿足即停止,將高頻條件前置
  4. 巢狀深度:避免超過 3 層巢狀,改用 CTE 或應用層邏輯
  5. 索引影響:WHERE CASE ... END = 'value' 無法使用索引,改寫為 WHERE (cond1 AND val1) OR (cond2 AND val2)...

版本差異提醒

  • MySQL 8.0+ 支援 CASE ... WHEN ... THEN ... ELSE ... END 標準語法外,無額外擴展
  • MariaDB 10.3+ 引入 RETURNING 子句可配合 CASE 做複雜更新
  • 舊版本(<5.0)不支援 ELSE 省略時的隱性 NULL,需顯式寫出

掌握 CASE 表達式的靈活運用,能將複雜業務邏輯下沉至資料庫層,減少應用層資料傳輸與處理,是 SQL 進階的必修課。

copyright © 萬盛學電腦網 all rights reserved