ORDER BY 默认升序,降序必须显式写DESC;多字段排序需分别指定方向,NULL行为因数据库而异。

降序排序必须显式写 DESC,不写默认升序,不是“自动识别”或“按字段类型推断”。
ORDER BY 后不加 DESC 就是升序,不是错误也不是警告
很多初学者以为省略 DESC 会报错或触发降序,实际完全相反:ORDER BY name 等价于 ORDER BY name ASC,永远升序。数据库不会猜测你想要什么顺序。
- 显式写
ASC或DESC是最佳实践,避免歧义 - 部分旧版 MySQL 在严格模式下可能警告隐式
ASC,但不中断执行 - 如果结果看起来“像降序”,大概率是数据本身有序或查询带了缓存/索引干扰,不是 SQL 行为
多个字段混合排序时,每个字段需单独指定 DESC/ASC
ORDER BY 支持多字段,但排序方向不继承——后一个字段不会“自动沿用前一个的 DESC”。
例如想先按 score 降序、再按 name 升序(同分时姓名靠前的排前面),必须写:
ORDER BY score DESC, name ASC
- 写成
ORDER BY score DESC, name是合法的,但name实际是ASC(默认) - 写成
ORDER BY score DESC, name DESC才是两个都降序 - 方向混用很常见,比如时间倒序 + ID 正序防分页重复
NULL 值在 DESC 排序中的位置取决于数据库实现
DESC 下 NULL 排在哪?MySQL、PostgreSQL、SQL Server 各不相同——这不是 bug,是标准允许的自由实现。
- MySQL:默认把
NULL当作“最小值”,DESC时排在最后 - PostgreSQL:默认把
NULL当作“最大值”,DESC时排在最前 - 如需跨数据库一致行为,显式用
ORDER BY col DESC NULLS LAST(PostgreSQL 支持),但 MySQL 不支持该语法,得用IS NULL模拟
真正容易出问题的不是语法,而是假设“写了 DESC 就万事大吉”——字段是否允许 NULL、是否用了函数包装(如 UPPER(name))、索引是否覆盖排序字段,这些都会让实际执行计划和返回顺序偏离预期。

















