函數定義對比
| 函數 | 語法 | 邏輯 | 返回類型 |
| IF() | IF(expr1, expr2, expr3) | expr1 為 TRUE 返回 expr2,否則 expr3 | 取決於 expr2/expr3 類型推導 |
| IFNULL() | IFNULL(expr1, expr2) | expr1 不為 NULL 返回 expr1,否則 expr2 | 取決於 expr1/expr2 類型推導 |
真值判斷規則(關鍵)
MySQL 中 **TRUE = 非 0 且非 NULL**。具體:
- 數字:
0 → FALSE,非 0 → TRUE(含負數)
- 字符串:
'' (空串) → FALSE,非空串 → TRUE(含 '0'、'false'、'null')
- NULL:
NULL → FALSE
- 布爾字面量:
TRUE=1、FALSE=0
IFNULL() 實測行為表
| expr1 | IFNULL(expr1, 100) | 說明 |
| NULL | 100 | NULL 返回備選 |
| 0 | 0 | 0 非 NULL,返回自身 |
| -10 | -10 | 負數非 NULL |
| 10 | 10 | 正數非 NULL |
| 'null' | 'null' | 字符串 'null' 非 NULL |
| false | 0 | FALSE=0 非 NULL |
| true | 1 | TRUE=1 非 NULL |
IF() 實測行為表
| expr1 | IF(expr1, 'yes', 'no') | 邏輯解析 |
| STRCMP('str','str1') → -1 | 'yes' | 非 0 → TRUE |
| 0 | 'no' | 0 → FALSE |
| NULL | 'no' | NULL → FALSE |
| 'null' | 'no' | 非空字符串但隱式轉數字 0 → FALSE ⚠ |
| false | 'no' | FALSE=0 → FALSE |
| -10 | 'yes' | 負數非 0 → TRUE |
| 10 | 'yes' | 正數非 0 → TRUE |
| '0' | 'no' | 字符串 '0' 隱式轉 0 → FALSE ⚠ |
⚠ 核心坑點:字符串隱式轉換為數字參與真值判斷!'abc' → 0 (FALSE),'1abc' → 1 (TRUE)。**永遠不要用字符串直接作 IF 條件**,需顯式比較:IF(str = 'target', ...)。
實戰應用模式
1. 空值降級/默認值
SELECT IFNULL(nickname, CONCAT('用戶', id)) AS display_name FROM users;
SELECT IFNULL(commission_rate, 0.05) * amount AS commission FROM orders;
2. 條件分支標籤化
SELECT
id,
IF(score >= 60, '及格', '不及格') AS result,
CASE
WHEN score >= 90 THEN '優秀'
WHEN score >= 80 THEN '良好'
WHEN score >= 60 THEN '及格'
ELSE '不及格'
END AS grade
FROM exams;
3. 動態排序/分組
SELECT * FROM products
ORDER BY
IF(@sort = 'price_asc', price, 0) ASC,
IF(@sort = 'price_desc', price, 0) DESC,
IF(@sort = 'sales', sales, 0) DESC;
4. 條件聚合(統計報表神器)
SELECT
DATE(created_at) AS day,
COUNT(*) AS total,
SUM(IF(status = 'paid', 1, 0)) AS paid_cnt,
SUM(IF(status = 'refund', amount, 0)) AS refund_amt
FROM orders
GROUP BY DATE(created_at);
5. NULL 安全比較(等價 <=>)
-- IFNULL 實現 NULL 安全等值
WHERE IFNULL(col1, '___NULL___') = IFNULL(col2, '___NULL___')
-- MySQL 原生 NULL 安全等值運算符
WHERE col1 <=> col2 -- 內部實現邏輯等同
性能與優化建議
IFNULL、IF 極輕量,**無顯著性能開銷**
- 避免在 WHERE/JOIN/ORDER BY 中對大字段使用函數導致索引失效
- 條件聚合 `SUM(IF(...))` 比 `CASE WHEN` 略快,可讀性略低
- 大量 NULL 列建議表設計階段給默認值,減少運行時判斷
總結
IFNULL(expr, val) 專治 **NULL 降級**,語義單一、性能極優;IF(cond, t, f) 通用 **三元條件**,但**字符串隱式轉數字判斷真值是巨坑**,務必顯式比較。條件聚合、動態排序、空值降級是兩大函數的高頻實戰舞臺。建立「數字/字符串/NULL 三類真值規則」心智模型,拒絕隱式轉換驚喜。