IS NOT NULL 仅过滤 NULL 值,不处理空字符串或空格;正确写法只能是 IS NULL/IS NOT NULL,不可用 = NULL;联合过滤需配合 TRIM(column) != '',且排序时需显式控制 NULL 位置。

IS NOT NULL 不能和空字符串混为一谈
很多人写 WHERE column IS NOT NULL 后仍看到“空白”数据,其实是碰到了空字符串 '' 或纯空格——这些都不是 NULL,IS NOT NULL 对它们完全无效。
真实场景中,比如用户表的 phone 字段:数据库里可能存了 NULL(未填写)、''(前端传了空字符串)、' '(带空格),三者行为完全不同。
-
NULL表示“未知/不存在”,任何与NULL的比较(包括= ''、!= '123')都返回UNKNOWN,即不被WHERE选中 -
''是合法字符串值,IS NOT NULL会包含它,但业务上往往也要排除 - 用
TRIM(column) != ''可同时过滤NULL、''和纯空格,但注意:在 MySQL 中TRIM(NULL)返回NULL,所以得先用IS NOT NULL或COALESCE
WHERE col IS NOT NULL 的写法必须避开 = NULL
新手常犯的错是写成 WHERE column = NULL 或 WHERE column != NULL —— 这俩永远不返回任何行,因为 SQL 标准规定 NULL = NULL 不成立,所有涉及 NULL 的等值比较结果都是 UNKNOWN,而 WHERE 只接受 TRUE。
正确写法只有两个:IS NULL 和 IS NOT NULL。这是语法关键词,不是函数,不能加括号,也不能用于表达式右侧。
- ❌ 错误:
WHERE status = NULL、WHERE NULL = status、WHERE status IS NOT NULL AND status != ''(后半段多余,但不报错) - ✅ 正确:
WHERE status IS NOT NULL、WHERE status IS NULL - ⚠️ 注意:某些方言如 PostgreSQL 支持
IS DISTINCT FROM,可安全比较含NULL的值,但标准 SQL 不通用
联合过滤空值和空字符串的实用组合
多数业务要求“有实际内容”,就得同时处理 NULL、''、全空格。最稳妥且跨数据库的方式是分步判断:
WHERE column IS NOT NULL AND TRIM(column) != ''
这条语句在 MySQL、PostgreSQL、SQL Server(需用 LTRIM(RTRIM()))、Oracle 都能跑通;SQLite 的 TRIM 从 3.28 开始支持。
- 如果字段是数字类型(如
INT),IS NOT NULL就够了,因为数字字段不可能存'' - 如果字段允许
''作为有效值(比如“未提供”和“明确为空”要区分),那就不能加TRIM判断,只用IS NOT NULL - 性能提示:对
TRIM(column) != ''加索引无效,除非用函数索引(如 PostgreSQL 的CREATE INDEX ON t ((TRIM(col))))
ORDER BY 里 NULL 的默认排序位置容易被忽略
IS NOT NULL 只管过滤,不管排序。但实际查出非空数据后,ORDER BY column 时 NULL 默认排最前(ASC)或最后(DESC),取决于数据库。例如 MySQL 和 PostgreSQL 默认把 NULL 当最大值,ORDER BY name ASC 会让 NULL 排末尾——可如果你刚用 IS NOT NULL 过滤过,这就不影响;但若没过滤,又想让非空值优先显示,就得显式控制:
ORDER BY (column IS NULL), column
这个技巧利用布尔表达式返回 0(FALSE)或 1(TRUE),把非空值全排前面,再按字段值排序。
真正容易被跳过的点是:过滤和排序逻辑分离,IS NOT NULL 解决不了排序中的隐式 NULL 行为,得单独处理。

















