SQL标准规定NULL在ASC时排最前、DESC时排最后,但实际行为因库而异:PostgreSQL遵循标准,MySQL 5.7+和SQL Server基本一致,Oracle 12c+已支持标准,旧版则默认NULL均排最后。

ORDER BY 中 NULL 默认排在哪?
SQL 标准规定:NULL 在升序(ASC)时被视为“最小值”,排在最前;降序(DESC)时被视为“最大值”,排在最后。但实际行为取决于数据库实现——比如 PostgreSQL 严格遵循标准,MySQL 5.7+ 和 SQL Server 也基本一致,而 Oracle 早期版本曾把 NULL 都排在最后(无论 ASC 还是 DESC),不过 12c+ 已支持标准行为。
让 NULL 排在最前(无论 ASC/DESC)
用 IS NULL 布尔表达式参与排序,它返回 TRUE(=1)或 FALSE(=0),可直接用于控制优先级:
SELECT * FROM users ORDER BY is_active IS NULL, is_active ASC;
说明:
-
is_active IS NULL先排:结果为TRUE(即NULL行)排在FALSE前 → 所有NULL在最前 - 再按
is_active ASC排非NULL值,保持原有顺序逻辑 - 这个写法在 PostgreSQL、MySQL 8.0+、SQL Server、SQLite 都有效
- 注意:MySQL 5.7 不支持在
ORDER BY中直接用布尔表达式,需改写为CASE WHEN is_active IS NULL THEN 0 ELSE 1 END
让 NULL 排在最后(无论 ASC/DESC)
同理,把布尔判断翻转即可:
SELECT * FROM users ORDER BY is_active IS NOT NULL, is_active ASC;
说明:
-
is_active IS NOT NULL为TRUE(非NULL)时值为 1,FALSE(NULL)时为 0 →FALSE排在TRUE后 →NULL落在最后 - 若想降序排列非
NULL值,写成is_active DESC即可,不影响NULL位置 - PostgreSQL 还支持更直白的
NULLS LAST语法:ORDER BY is_active ASC NULLS LAST,但 MySQL 和 SQL Server 不支持该关键字
不同数据库的兼容性陷阱
跨库迁移时最容易栽在这里:
- MySQL 5.7 及更早版本不接受
expr IS NULL直接进ORDER BY,必须用CASE模拟:ORDER BY CASE WHEN is_active IS NULL THEN 1 ELSE 0 END, is_active ASC - SQL Server 对
IS NULL排序支持良好,但注意其TEXT/NTEXT类型列不能直接参与ORDER BY,会报错Cannot sort a row of size … - SQLite 默认把
NULL排最后(与标准相反),但从 3.30.0 开始已修正为标准行为;若用旧版,必须显式用IS NULL控制 - Oracle 12c+ 支持
NULLS FIRST/NULLS LAST,但老版本只能靠NVL或DECODE伪造值(比如ORDER BY NVL(is_active, -999999)),易引发类型隐式转换问题
实际写法得先看 SELECT version(); 或文档确认当前环境对空值排序的默认策略和扩展语法支持程度。

















