在 SQL 中判断数据是否为空(NULL
)需要特别注意以下关键事项,这些是实际开发中最常见的陷阱:
IS NULL
/ IS NOT NULL
-- ✅ 正确写法
SELECT * FROM users WHERE phone IS NULL; -- 查空值
SELECT * FROM users WHERE phone IS NOT NULL; -- 查非空
-- ❌ 致命错误写法(永远无效!)
SELECT * FROM users WHERE phone = NULL; -- 错误!
SELECT * FROM users WHERE phone != NULL; -- 错误!
原因:
NULL
代表 未知值/缺失值,在 SQL 逻辑中:
NULL = NULL
→ 结果不是 TRUE
而是 UNKNOWN
NULL
的比较都返回 UNKNOWN
WHERE
子句只返回条件为 TRUE
的行(过滤掉 UNKNOWN
)SELECT
COUNT(phone) AS not_null_count, -- 只统计非空值
COUNT(*) AS total_rows -- 统计所有行(含NULL)
FROM users;
AVG()
、SUM()
等聚合函数 自动跳过 NULL
COUNT(*)
统计所有行(包括 NULL
值行)SELECT 10 + NULL; -- 结果 → NULL
SELECT 100 / NULL; -- 结果 → NULL
任何包含 NULL
的算术运算结果都是 NULL
SELECT NULL AND TRUE; -- 结果 → NULL
SELECT NULL OR FALSE; -- 结果 → NULL
SELECT NOT NULL; -- 结果 → NULL
TRUE
/FALSE
/UNKNOWN
(NULL
参与时可能返回 UNKNOWN
)特性 | NULL |
'' (空字符串) |
---|---|---|
数据类型 | 表示"未知" | 有效的字符串值 |
存储占用 | 无数据存储 | 占用存储空间(长度0) |
比较结果 | NULL = NULL → 未知 |
'' = '' → TRUE |
查询方式 | WHERE col IS NULL |
WHERE col = '' |
示例:
INSERT INTO test VALUES (NULL), ('');
-- 区分查询:
SELECT * FROM test WHERE col IS NULL; -- 只返回 NULL
SELECT * FROM test WHERE col = ''; -- 只返回空字符串
-- 将 NULL 转为默认值
SELECT COALESCE(phone, 'N/A') FROM users; -- NULL → 'N/A'
-- 条件判断(类似三元表达式)
SELECT IFNULL(phone, '未填写') FROM users; -- MySQL
SELECT NVL(phone, '未知') FROM employees; -- Oracle
-- 同时检测 NULL 和空字符串
SELECT * FROM products
WHERE COALESCE(description, '') = '';
-- 或使用
WHERE description IS NULL OR description = '';
NOT NULL
约束(可提升索引效率)NULL
)陷阱1:NOT IN 子查询包含 NULL
-- 错误示例(返回空结果)
SELECT * FROM orders
WHERE customer_id NOT IN (
SELECT id FROM customers WHERE status = 'inactive' -- 子查询可能含 NULL
);
✅ 修正方案:
SELECT * FROM orders
WHERE customer_id NOT IN (
SELECT id FROM customers
WHERE status = 'inactive'
AND id IS NOT NULL -- 显式排除 NULL
);
陷阱2:连接查询的 NULL 匹配
-- 内连接会过滤掉 NULL 关联的行
SELECT *
FROM employees e
JOIN departments d ON e.dept_id = d.id; -- dept_id 为 NULL 的员工不会出现
✅ 解决方案:
-- 使用左连接保留 NULL 关联行
SELECT *
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.id;
表设计时:
NULL
(用 NOT NULL
约束强制非空)DEFAULT ''
或 DEFAULT 0
)查询时:
IS NULL
判断空值COALESCE
转换业务逻辑:
NULL
(未设置)和空字符串(用户主动清空)的业务含义