判断 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,整个条件就失效——这种错误不会报错,只会静默返回空结果,最难排查。
