MySQL 提供 IFNULL()、IF()、CASE 三種條件邏輯函數,雖然功能有重疊,但適用場景與行為細節差異巨大。掌握它們的精確語義,能寫出更簡潔、高效且無 Bug 的 SQL。
SELECT IFNULL(1, 0); -- 1
SELECT IFNULL(NULL, 10); -- 10
SELECT IFNULL(1/0, 10); -- 10 (除零產生 NULL)
SELECT IFNULL(1/0, 'yes'); -- 'yes' (回傳類型隨上下文)
關鍵特性:
expr1 IS NULL,0、''、FALSE 皆視為非 NULLCOALESCE(expr1, expr2),但 COALESCE 支援多參數,建議優先使用SELECT IF(1>2, 2, 3); -- 3
SELECT IF(1<2, 'yes', 'no'); -- 'yes'
SELECT IF(STRCMP('test','test1'),'yes','no'); -- 'no' (STRCMP 相等回傳 0)
SELECT IF(0.1, 1, 0); -- 0 !!! 因為 0.1 轉整數變 0,視為 FALSE
SELECT IF(0.1 <> 0, 1, 0); -- 1 正確:明確比較後再判斷
鐵律:expr1 在數值語境下會被轉為整數再判斷真偽。測試浮點數或字串時,必須使用比較運算子(<>0、IS NOT NULL、='value' 等)產生布林結果。
SELECT CASE 1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END; -- 'one'
SELECT CASE WHEN 1>0 THEN 'true' ELSE 'false' END; -- 'true'
SELECT CASE BINARY 'B' WHEN 'a' THEN 1 WHEN 'b' THEN 2 END; -- NULL (BINARY 區分大小寫)
SELECT CASE 'B' WHEN 'a' THEN 1 WHEN 'b' THEN 2 END; -- 2 (預設不區分大小寫)
COALESCE(col, default_val)(標準、多參數、可讀性最佳)IF(condition, true_val, false_val)(簡潔,但記得比較運算子)CASE WHEN ... THEN ... ELSE ... END(結構清晰、支援巢狀、標準 SQL)CASE BINARY ... 或 IF(BINARY col='val', ...)WHERE IFNULL(col,0)=1),改寫為 WHERE col=1 OR col IS NULL 以利用索引CASE 運算式在 SELECT 列表中可被優化器常數摺疊,條件為常數時極快條件判斷看似簡單,細節決定成敗。尤其 IF() 的隱式整數轉換陷阱,是無數開發者深夜除錯的元兇——現在你知道了,就不會再踩坑。