蓝易云cdn:sql order by排序null值
SQL ORDER BY 排序时 NULL 放最后,怎么写?🧠
在数据库中,NULL 代表“未知值”,而不是 0 或空字符串。
不同数据库对 NULL 的默认排序规则不同:
- 有些数据库在 升序(ASC) 时会把
NULL放前面 - 有些数据库在 降序(DESC) 时会把
NULL放后面
如果业务明确要求:无论升序还是降序,都把 NULL 排到最后,就必须显式控制排序逻辑。
下面给出严谨且通用的写法。
一、标准 SQL 写法(推荐方式)🚀
在支持标准语法的数据库中(如 PostgreSQL、Oracle 等):
SELECT *
FROM 表名
ORDER BY 字段名 ASC NULLS LAST;
降序:
SELECT *
FROM 表名
ORDER BY 字段名 DESC NULLS LAST;
NULLS LAST 明确告诉数据库:NULL 永远排在最后。
这是语义最清晰、可读性最高的写法。
二、MySQL / MariaDB 通用写法(重点)🔥
MySQL 不支持 NULLS LAST 关键字,需要用逻辑表达式实现。
方法一:使用 IS NULL(推荐)
SELECT *
FROM 表名
ORDER BY 字段名 IS NULL, 字段名 ASC;
原理解释:
字段名 IS NULL会返回:- 0(非 NULL)
- 1(是 NULL)
- 排序时 0 在前,1 在后
- 然后再按字段值排序
降序写法:
ORDER BY 字段名 IS NULL, 字段名 DESC;
这是目前 MySQL 场景下最稳定、性能友好的方式。
方法二:使用 CASE 表达式
ORDER BY
CASE WHEN 字段名 IS NULL THEN 1 ELSE 0 END,
字段名 ASC;
逻辑与上面一致,只是写法更显式。
优点是兼容性好,几乎所有数据库都支持。
三、SQL Server 写法 💡
SQL Server 同样不支持 NULLS LAST,推荐写法:
ORDER BY
CASE WHEN 字段名 IS NULL THEN 1 ELSE 0 END,
字段名 ASC;
逻辑完全一致。
四、核心原理说明 📊
排序本质是比较大小。
我们人为构造一个“优先级字段”:
| 是否为 NULL | 排序权重 |
|---|---|
| 非 NULL | 0 |
| NULL | 1 |
排序时先按权重排序,再按真实字段排序。
这就是控制 NULL 位置的根本逻辑。
五、性能注意事项 ⚠️
- 若字段有索引,
字段名 IS NULL仍然可以利用索引排序。 - 复杂 CASE 可能导致无法走纯索引排序,需结合执行计划验证。
- 在高并发业务(例如日志查询、报表系统)建议优先使用
IS NULL方式。
六、实战示例 🎯
假设有表:
| id | score |
|---|---|
| 1 | 90 |
| 2 | NULL |
| 3 | 85 |
目标:升序且 NULL 在最后
SELECT *
FROM student
ORDER BY score IS NULL, score ASC;
结果:
85
90
NULL
总结
- 标准 SQL:使用
NULLS LAST - MySQL / SQL Server:使用
字段 IS NULL排序 - 原理:人为构造排序优先级
这不是技巧,而是排序逻辑的精确控制。
掌握这个,你的报表排序不会再出现“数据跑到顶部”的异常现象。📈