必须用 IS NULL 判断 NULL,因 NULL 表示未知值,= NULL 恒返回 UNKNOWN 导致查询无结果;IS NULL 是 SQL 标准语法,可安全组合 AND/OR,且需区分 NULL、空字符串和空格。

判断 NULL 必须用 IS NULL,不是 = NULL
MySQL 中 NULL 表示“未知值”,不是空字符串 '',也不是数字 0,更不是布尔假。它无法参与常规比较运算——所有形如 col = NULL、col != NULL、col NULL 的写法,结果恒为 UNKNOWN(在 WHERE 中等价于 FALSE),因此查不到任何数据。
-
正确写法:
SELECT * FROM users WHERE phone IS NULL;
-
错误写法(看似合法,实则永远无结果):
SELECT * FROM users WHERE phone = NULL;
-
IS NULL是 SQL 标准语法,在 MySQL、PostgreSQL、SQL Server 等主流数据库中通用;而ISNULL()函数是 MySQL 特有(且与 SQL Server 的同名函数语义不同),不推荐用于条件判断
IS NULL 和 IS NOT NULL 可安全组合其他条件
实际查询中,空值判断常需与其他逻辑并存,比如“电话为空且注册时间早于一年前”。这时 IS NULL 可像普通布尔表达式一样参与 AND/OR 运算,无兼容性或语义风险。
- 查找既没填邮箱也没填电话的用户:
SELECT * FROM users WHERE email IS NULL AND phone IS NULL;
- 查找邮箱为空或地址为空的用户:
SELECT * FROM users WHERE email IS NULL OR address IS NULL;
- 注意:若字段有索引,
IS NULL在部分场景下仍可走索引(尤其当列允许 NULL 且统计信息准确时),但不如等值查询高效;避免在大表上对无索引字段高频执行IS NULL
区分 NULL 和空字符串 '' 是常见翻车点
很多开发者误以为“没填就是空”,但数据库里可能存的是 NULL(未赋值)、''(显式提交了空字符串)、甚至全是空格的 ' '。三者行为完全不同:
-
WHERE name = ''→ 只匹配明确存了空字符串的行 -
WHERE name IS NULL→ 只匹配从未赋值或显式设为NULL的行 - 若需同时查出两者,必须显式写出:
SELECT * FROM users WHERE name IS NULL OR name = '';
- 插入时建议统一策略:如业务上“未填写”一律存
NULL,避免混用;建表时用NOT NULL DEFAULT ''或NOT NULL DEFAULT '未知'也能从源头减少歧义
应用层处理 NULL 要主动防御,别依赖数据库“默认不报错”
即使 SQL 写对了,后端代码(如 Java 的 ResultSet.getObject()、Python 的 pymysql.fetchone())拿到 NULL 后若直接调用方法或解包,极易触发 NullPointerException 或 TypeError。
- Java 示例中应先检查:
if (rs.wasNull())或使用Optional.ofNullable() - Python 中建议用
row["email"] or "未提供"前提是确认该字段不会存'';更稳妥用row.get("email") or "未提供" -
前端展示时,
IFNULL(email, '—')比在 JS 里反复判空更简洁可靠
NULL 不是值,是状态;IS NULL 不是技巧,是规则。哪怕只漏掉一个 IS,整个条件就失效——这种错误不会报错,只会静默返回空结果,最难排查。










