在 SQL 里,NULL 表示未知或不存在的值,而空字符串 '' 是一个长度为零的具体字符串。这两种情况在比较、运算和函数处理时经常表现出完全不同的行为,如果理解不清晰,很容易写出统计不准或过滤失效的查询。

一、等值比较的差异
使用等于号(=)比较 NULL 时,结果既不是真也不是假,而是未知,因此普通条件无法匹配 NULL 行。
-- 以下语句查不到 name 为 NULL 的记录 SELECT * FROM user WHERE name = NULL; -- 正确写法 SELECT * FROM user WHERE name IS NULL; -- 空字符串可以用等于号比较 SELECT * FROM user WHERE name = '';
二、排序行为不同
在 ORDER BY 中,NULL 通常被视为最小值(MySQL、PostgreSQL 默认),排在最前;空字符串则作为一个真实字符串参与排序,一般排在普通字符之前但位于 NULL 之后(取决于数据库)。
| 数据库 | NULL 位置 | 空字符串位置 |
|---|---|---|
| MySQL | 最前 | 在 NULL 后,普通字符前 |
| PostgreSQL | 最前(可指定 NULLS LAST) | 作为普通串处理 |
| Oracle | 最后(可指定 NULLS FIRST) | 作为普通串处理 |
三、聚合函数与统计
COUNT(*) 会统计所有行,而 COUNT(列名) 会忽略该列为 NULL 的行,但不会忽略空字符串。SUM、AVG 等也直接跳过 NULL。
-- 统计 name 非 NULL 的行,空字符串也算 SELECT COUNT(name) FROM user; -- 只统计 name 既非 NULL 也非空串 SELECT COUNT(*) FROM user WHERE name IS NOT NULL AND name <> ''; </code>
四、字符串拼接与函数
在 MySQL 中,NULL 参与 concat 会使结果为 NULL;空字符串参与则正常拼接。在 PostgreSQL 中,NULL 被视作空串处理。
-- MySQL 示例
SELECT CONCAT('a', NULL) AS r1, CONCAT('a', '') AS r2;
-- 结果:r1 为 NULL,r2 为 a
-- PostgreSQL 示例
SELECT 'a' || NULL AS r1, 'a' || '' AS r2;
-- 结果:r1 为 a,r2 为 a
五、逻辑判断中的注意点
在 CASE 或 WHERE 里,应先判断 NULL,再判断空串,否则 NULL 行会落入 ELSE 分支。
SELECT
CASE
WHEN col IS NULL THEN '缺失'
WHEN col = '' THEN '空串'
ELSE '有值'
END AS status
FROM sample;
小结
NULL 与空字符串 '' 的核心区别在于:NULL 是未知的标记,不能用普通比较运算符处理;空字符串是确定的零长度文本。写查询时建议显式区分 IS NULL 与 = '',并在统计前明确业务上是否把空串视作缺失,这样才能保证结果符合预期。
SQLNULLempty_string修改时间:2026-07-26 11:36:20