SQL多字段排序优先级由ORDER BY字段书写顺序严格决定:从左到右逐级生效,首字段为主排序依据,值相同时才按次字段排序;方向需显式声明,NULL须显式处理,索引须与排序顺序完全匹配。

SQL中多个字段排序的优先级完全由ORDER BY后字段的书写顺序决定:从左到右,逐级生效。
字段顺序就是优先级顺序
数据库先按第一个字段值分组排序;只有该字段值相等的行,才会进入第二个字段的比较;依此类推。这不是“同时考虑多个字段”,而是严格的层级关系。
- 正确示例:
ORDER BY status, created_at DESC→ 先按状态分大类,同类中再按时间倒序 - 错误写法:
ORDER BY created_at DESC, status→ 所有记录先按时间排,状态只在时间相同时起作用 - 验证方法:挑几行
status相同的记录,看它们是否真正按created_at DESC排列
每个字段的方向必须显式声明
ASC可省略,但DESC不能省;且方向是独立控制的,不会继承或默认统一。
-
ORDER BY name, age DESC表示 name 升序、age 降序 - 误写成
ORDER BY name DESC, age→ name 降序、age 升序(不是两个都降序) - 推荐做法:所有字段都写明方向,如
ORDER BY name DESC, age DESC
NULL值必须显式处理
不同数据库对NULL的默认排序位置不一致(MySQL升序时NULL在最前,PostgreSQL在最后),跨库迁移易出错。
- 通用写法:
ORDER BY (deadline IS NULL), deadline ASC→ FALSE(0)在前,TRUE(1)在后 - PostgreSQL支持:
ORDER BY deadline ASC NULLS LAST - CASE WHEN方式:
ORDER BY CASE WHEN reviewer_id IS NULL THEN 0 ELSE 1 END, created_at DESC
索引要严格匹配排序顺序才能生效
如果查询带WHERE user_id = 123且ORDER BY status, created_at DESC,理想索引是(user_id, status, created_at)。
- WHERE条件字段必须放索引最左
- ORDER BY字段顺序和方向必须与索引完全一致
- 用
EXPLAIN检查Extra列是否出现Using filesort,有则说明未走索引排序










