NULL 表示一个缺失或未知的值——它不是零,也不是空字符串,而是值的缺失。NULL 在比较、聚合和逻辑运算中具有特殊的、有时令人意外的行为——使其成为一个常见的 bug 来源。
NULL 即“未知”——与 NULL 的比较
email
email
email
email
NULL 表示一个缺失或未知的值——它不是零,也不是空字符串,而是值的缺失。NULL 在比较、聚合和逻辑运算中具有特殊的、有时令人意外的行为——使其成为一个常见的 bug 来源。
email
email
email
email
因为 NULL 意味着“未知”,任何与 NULL 的比较都会得出“未知”(而非真),所以 = NULL 永远不会匹配。你必须使用 IS NULL/IS NOT NULL——这是最常见的 NULL 错误。
SQL uses THREE-valued logic: TRUE, FALSE, and UNKNOWN (NULL).
NULL = NULL → UNKNOWN (not true!)
NULL AND true → UNKNOWN
NULL OR true → TRUE
NOT NULL → UNKNOWN
→ Conditions evaluating to UNKNOWN are treated as not-matching by WHERE.
-- aggregates IGNORE NULLs (except COUNT(*))
SELECT AVG(salary) FROM employees; -- averages only non-NULL salaries
SELECT COUNT(salary) FROM employees; -- counts only non-NULL (vs COUNT(*) = all rows)
-- arithmetic with NULL → NULL
SELECT price + NULL; -- NULL (any operation with NULL is NULL)
聚合函数会跳过 NULL,而任何涉及 NULL 的算术运算都会产生 NULL。
-- COALESCE — return the first non-NULL value (provide a default)
SELECT COALESCE(phone, 'No phone') FROM users; -- 'No phone' if phone is NULL
SELECT COALESCE(nickname, name, 'Unknown') FROM users; -- first non-NULL
-- NULLIF — return NULL if two values are equal
SELECT NULLIF(value, 0); -- NULL if value is 0 (e.g. avoid divide-by-zero)
COALESCE 为 NULL 提供回退值(用于默认值时非常常见),而 NULLIF 在满足条件时将值转换为 NULL。
理解 NULL 的行为对于编写正确的 SQL 至关重要,因为 NULL 的特殊语义是细微 bug 的常见来源——而 NULL 在真实数据中频繁出现(可选字段、缺失值、未匹配的连接)。
最关键且最常被弄错的一点是 NULL 意味着“未知”,因此你不能用 = 来与它比较(一个臭名昭著的 bug 是 WHERE col = NULL 会悄无声息地返回空结果);你必须使用 IS NULL/IS NOT NULL。
理解 SQL 的三值逻辑(TRUE/FALSE/UNKNOWN,其中与 NULL 的比较会得出 UNKNOWN 并被视为不匹配)可以解释一系列令人困惑的行为,对于正确编写条件非常重要。
了解聚合函数会忽略 NULL(影响 AVG、COUNT 等——有时会出人意料)、与 NULL 的算术运算会产生 NULL,以及如何用 COALESCE(提供默认值/回退值——一个非常常见的需求)和 NULLIF 来处理 NULL,都是实用且经常应用的知识。
由于 NULL 在真实数据库中无处不在(任何可空列、任何 LEFT JOIN),并且由于 NULL 不直观的行为(尤其是比较问题和三值逻辑)会导致真实且难以调试的 bug,理解 NULL 如何表现——比较、逻辑、聚合和处理——是编写正确 SQL 时核心的、必知的知识,也是一个常见的面试话题,能揭示对数据库中一个经常被错误处理的方面的理解。