處理 NULL 與多值匹配是 SQL 寫作高頻場景。MySQL 提供 IFNULL() 替代標準 ISNULL(),並支援 IN 簡化 OR 鏈。本文通過實例對比說明用法與陷阱。
IFNULL:MySQL 專用空值替換
-- 語法:IFNULL(expr1, expr2)
-- expr1 不為 NULL 返回 expr1,否則返回 expr2
SELECT IFNULL(1, 0); -- 1
SELECT IFNULL(1/0, 'default'); -- 'default' (1/0 產生 NULL)
SELECT IFNULL(NULL, 'fallback'); -- 'fallback'
對比:ISNULL vs IFNULL vs COALESCE
| 函數 | 參數數 | 標準 | 行為 | 建議 |
ISNULL(expr) | 1 | MySQL 專有 | 僅判斷是否 NULL,返回 0/1,不支援替換 | 勿用於替換 |
IFNULL(expr1, expr2) | 2 | MySQL 專有 | 兩參數替換 | 簡單雙值替換首選 |
COALESCE(v1, v2, ...) | N | ANSI SQL | 返回第一個非 NULL 值 | 多備選值/跨資料庫首選 |
實戰:查詢時將 NULL 顯示為預設值
SELECT id, IFNULL(nickname, '匿名用戶') AS display_name
FROM users;
IN 操作符:簡化多值 OR 條件
反模式:OR 鏈
SELECT product
FROM ProductParameter
WHERE val = 19116 OR val = 19127 OR val = 19128 OR val = 19119;
正規寫法:IN 列表
SELECT product
FROM ProductParameter
WHERE val IN (19116, 19127, 19128, 19119);
- 可讀性大幅提升,優化器易轉為
Range 掃描。
- 列表常數建議 不超過 1000 個,超過請用臨時表
JOIN。
進階:NOT IN 陷阱與 NOT EXISTS 替代
-- 危險:若子查詢結果含 NULL,NOT IN 永遠返回空集
SELECT * FROM a WHERE id NOT IN (SELECT b_id FROM b);
-- 安全:NOT EXISTS
SELECT * FROM a WHERE NOT EXISTS (SELECT 1 FROM b WHERE b.b_id = a.id);
組合招:IFNULL + IN 實戰
-- 查詢狀態為 1、2 或 NULL 的訂單
SELECT * FROM orders
WHERE IFNULL(status, 0) IN (1, 2); -- NULL 視為 0,不在集合中,被過濾
-- 或顯式包含 NULL
SELECT * FROM orders
WHERE status IN (1, 2) OR status IS NULL;
掌握 IFNULL/COALESCE 處理空值、IN 簡化集合判斷、NOT EXISTS 規避 NULL 陷阱,SQL 寫法更簡潔、執行計畫更穩定。
copyright ©
萬盛學電腦網 all rights reserved