null值在order by中默认位置因数据库而异:postgresql/oracle默认asc时排最后、desc时排最前,mysql 8.0+默认asc时排最前;必须显式使用nulls first/last确保跨库一致性。

NULL值在ORDER BY中默认排在哪?
SQL标准里,NULL在升序(ASC)时默认排最前,降序(DESC)时默认排最后——但这是可改的。窗口函数如ROW_NUMBER()、RANK()、LEAD()等,其排序行为完全继承自ORDER BY子句,所以控制NULL位置的关键不在窗口函数本身,而在ORDER BY里的NULLS FIRST或NULLS LAST。
PostgreSQL/Oracle/SQL Server 2022+ 怎么显式指定NULL位置
这些数据库支持标准SQL的NULLS FIRST/NULLS LAST语法,直接写在ORDER BY表达式后即可:
SELECT name, score,
ROW_NUMBER() OVER (ORDER BY score DESC NULLS LAST) AS rn
FROM students;
常见用法:
-
ORDER BY col ASC NULLS FIRST:升序,NULL排最前(和默认一致,但显式写出更可靠) -
ORDER BY col ASC NULLS LAST:升序,NULL排最后(覆盖默认行为) -
ORDER BY col DESC NULLS FIRST:降序,NULL排最前(常用于“把空值当最高优先级”场景)
MySQL 8.0+ 和 SQLite 怎么绕过不支持NULLS FIRST/LAST的问题
MySQL 8.0+ 实际已支持NULLS FIRST/NULLS LAST,但部分旧版本或配置下可能被禁用;SQLite 则至今不支持该语法。此时需用表达式模拟:
- 让
NULL排最后(升序):ORDER BY col IS NULL, col - 让
NULL排最前(升序):ORDER BY col IS NOT NULL, col - 让
NULL排最后(降序):ORDER BY col IS NULL, col DESC - 让
NULL排最前(降序):ORDER BY col IS NOT NULL, col DESC
原理是布尔表达式col IS NULL返回1(真)或0(假),按数值排序,再叠加主字段排序。注意括号不是必须的,但加了更清晰:ORDER BY (col IS NULL), col DESC。
窗口函数里混用NULL处理和PARTITION BY要注意什么
在PARTITION BY分组内单独控制NULL排序位置,没问题;但容易忽略的是:NULL值是否属于同一分区,取决于PARTITION BY表达式本身的NULL语义——比如PARTITION BY category,所有category IS NULL的行会被归入同一个分区,这个行为无法通过ORDER BY改变。
- 如果想把
NULL分区也排除在外,得提前用WHERE category IS NOT NULL - 若
category有大量NULL,又需要按不同逻辑排序,考虑用CASE WHEN构造伪分类:PARTITION BY COALESCE(category, 'unknown') -
ORDER BY中的NULLS FIRST只影响排序顺序,不影响ROWS BETWEEN这类帧定义的范围计算
真正容易出错的地方,是以为改了ORDER BY就能让NULL“消失”或跨分区移动——它只管顺序,不管归属。










