NULL ≠ 0 ≠ '' (空字符串)。NULL 表示「不知道值是多少」或「這個屬性不存在」。
SELECT 1 = NULL, 1 != NULL, 1 < NULL, 1 > NULL;
-- 結果全為 NULL (在 WHERE 中視為 FALSE)
-- 正確判斷
SELECT 1 IS NULL, 1 IS NOT NULL;
-- 結果: 0 (FALSE), 1 (TRUE)
鐵律:永遠用 IS NULL / IS NOT NULL 判斷 NULL,絕不使用 =、!=、<、>。
SELECT NULL, 1 + NULL, CONCAT('Invisible', NULL);
-- 結果全為 NULL
任何包含 NULL 的算術/字符串/函數運算,結果均為 NULL (除非函數文檔明確說明處理 NULL,如 IFNULL、COALESCE、CONCAT_WS)。
-- 錯誤:永遠返回空結果
SELECT * FROM my_table WHERE phone = NULL;
-- 正確
SELECT * FROM my_table WHERE phone IS NULL; -- 找 NULL
SELECT * FROM my_table WHERE phone = ''; -- 找空字符串
SELECT * FROM my_table WHERE phone IS NULL OR phone = ''; -- 找「無電話」
| 場景 | 行為 | 注意 |
|---|---|---|
| 索引列 | MyISAM/InnoDB 5.6+ 允許索引 NULL 列,但**主鍵列不能為 NULL** | 早期版本不允許索引 NULL 列 |
| ORDER BY | ASC 時 NULL 排最前,DESC 時 NULL 排最後 | ORDER BY col IS NULL, col 可控制 NULL 位置 |
| GROUP BY | 所有 NULL 視為同一組 | COUNT(col) 不統計 NULL,COUNT(*) 統計行數含 NULL |
| UNIQUE 索引 | 允許**多個 NULL** (視為不同值) | SQL Server 僅允許一個 NULL,差異巨大! |
| 首個 TIMESTAMP 列插入 NULL | 自動賦值為當前時間 | 特殊行為,非標準 NULL 語義 |
| AUTO_INCREMENT 列插入 NULL/0 | 自動生成下一個序列值 | 標準行為 |
| 函數 | 語法 | 說明 | 示例結果 |
|---|---|---|---|
IFNULL | IFNULL(expr1, expr2) | expr1 不為 NULL 返回 expr1,否則返回 expr2 | IFNULL(NULL, 'N/A') → 'N/A' |
COALESCE | COALESCE(expr1, expr2, ...) | 返回第一個非 NULL 參數,**標準 SQL,多參數首選** | COALESCE(NULL, NULL, 3, 4) → 3 |
NULLIF | NULLIF(expr1, expr2) | expr1 = expr2 返回 NULL,否則返回 expr1 | NULLIF(5, 5) → NULL |
ISNULL | ISNULL(expr) | expr 為 NULL 返回 1,否則 0 (MySQL 專用,等同 expr IS NULL) | ISNULL(NULL) → 1 |
CONCAT_WS | CONCAT_WS(sep, str1, str2, ...) | 跳過 NULL 參數拼接,**拼接字段首選** | CONCAT_WS(',', 'a', NULL, 'c') → 'a,c' |
NULL = 未知/不適用,''/0 = 已知為空/零。表設計時明確註釋status TINYINT NOT NULL DEFAULT 0,避免 NULL 污染邏輯判斷WHERE col = 'value' OR col IS NULL 視業務而定,勿漏判SUM(col) 忽略 NULL,全 NULL 返回 NULL (非 0)。用 COALESCE(SUM(col), 0) 兜底