MySQL 提供 CASE、IF()、IFNULL()、NULLIF() 四大條件運算式,可在查詢層直接完成資料轉換、邏輯判斷與空值處理,減少應用層代碼。本文系統整理語法、型別推導規則與實戰範例。
CASE value
WHEN compare_value THEN result
[WHEN ... THEN ...]
[ELSE result]
END
CASE
WHEN condition THEN result
[WHEN ... THEN ...]
[ELSE result]
END
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(區分大小寫)
THEN/ELSE 回傳型別的「相容集合」:字串 > 浮點數 > 整數IF(expr1, expr2, expr3)
-- expr1 為 TRUE(非 0 且非 NULL)回傳 expr2,否則 expr3
SELECT IF(1>2, 2, 3); -- 3
SELECT IF(1<2, 'yes', 'no'); -- 'yes'
SELECT IF(STRCMP('test','test1'),'no','yes'); -- 'no'
SELECT IF(0.1, 1, 0); -- 0 (0.1→0 視為 FALSE)
SELECT IF(0.1<>0, 1, 0); -- 1 (明確比較保留浮點語意)
結論:條件表達式務必使用比較運算子(<>0、IS NOT NULL),避免非預期的整數轉換。
| expr2 / expr3 型別組合 | 結果型別 |
|---|---|
| 任一為字串 | 字串 |
| 任一為浮點數 | 浮點數 |
| 皆為整數 | 整數 |
IFNULL(expr1, expr2)
-- expr1 不為 NULL 回傳 expr1,否則 expr2
SELECT IFNULL(1,0); -- 1
SELECT IFNULL(NULL,10); -- 10
SELECT IFNULL(1/0,10); -- 10 (除零產生 NULL)
SELECT IFNULL(1/0,'yes'); -- 'yes'
CREATE TABLE tmp SELECT IFNULL(1,'test') AS test;
-- test 欄位型別變為 CHAR(4)
NULLIF(expr1, expr2)
-- 相等回傳 NULL,否則 expr1
-- 等價:CASE WHEN expr1=expr2 THEN NULL ELSE expr1 END
SELECT NULLIF(1,1); -- NULL
SELECT NULLIF(1,2); -- 1
參數不相等時會兩次評估 expr1,若 expr1 為複雜運算或函數呼叫,需注意效能影響。
SELECT name,
CASE sex WHEN 'M' THEN '男' WHEN 'F' THEN '女' ELSE '未知' END AS gender
FROM users;
SELECT product_name, IFNULL(discount, 0) AS discount_rate FROM products;
SELECT amount / NULLIF(count, 0) AS avg_amount FROM stats;
SELECT
SUM(CASE WHEN status='paid' THEN amount ELSE 0 END) AS paid_total,
SUM(CASE WHEN status='refund' THEN amount ELSE 0 END) AS refund_total
FROM orders;
善用條件運算式,讓 SQL 承擔更多業務邏輯,應用層更輕量、效能更穩定。