必须显式写DESC才能降序,不加默认ASC升序;多字段排序中DESC仅作用于紧邻字段,如ORDER BY status ASC, created_at DESC表示先按状态升序、再按时间降序。

ORDER BY 子句加 DESC 是唯一可靠方式,不加就默认升序,别指望数据库猜你想要倒着排。
必须显式写 DESC,否则就是升序
很多新手写完 SELECT * FROM logs ORDER BY created_at,发现最新数据没在最上面——因为没写 DESC,数据库按默认 ASC 排了。只要想“时间倒序”,就得手敲 DESC,不能省略。
常见错误现象:
- 查日志表时
created_at最大的记录排在最后 - 订单按
updated_time排,但最新更新的反而靠后
正确写法示例:
SELECT * FROM orders ORDER BY updated_time DESC;
多字段排序时,DESC 只作用于紧邻的字段
ORDER BY a, b DESC 的意思是:先按 a 升序,再按 b 降序;不是整个都降序。如果两个都要降序,必须都写:
-
ORDER BY a DESC, b DESC✅ -
ORDER BY a, b DESC❌(a实际是升序)
典型使用场景:先按状态分组,组内按时间倒序取最新一条
SELECT * FROM tasks ORDER BY status ASC, created_at DESC;
NULL 值位置因数据库而异,别依赖默认行为
MySQL 默认 NULL 排在最前(升序时),PostgreSQL 和 SQL Server 默认排在最后(升序时)。一旦字段可能为 NULL,又要求“有值的最新记录优先”,光靠 DESC 不够。
稳妥做法是显式控制 NULL 位置:
- MySQL / PostgreSQL:用
IS NULL布尔表达式垫底 - PostgreSQL 还支持
NULLS LAST(标准 SQL) - SQL Server 要用
CASE WHEN或ISNULL
例如 MySQL 中让非空时间优先、且倒序:
SELECT * FROM events ORDER BY created_at IS NULL, created_at DESC;
带 WHERE 时,顺序不能颠倒
WHERE 必须在 ORDER BY 之前。写成 ORDER BY ... WHERE ... 会直接报错 Syntax error near WHERE。
执行逻辑固定为:FROM → WHERE → SELECT → ORDER BY。漏掉 WHERE 还能跑,但顺序反了就语法失败。
正确结构:
SELECT id, title FROM articles WHERE published = 1 ORDER BY publish_time DESC;
真正容易被忽略的是:不同数据库对 NULL 的默认排序方向不一致,而且 ORDER BY 后面不写 ASC/DESC 就不是“省略”,而是明确选择了升序——这个隐含约定,在跨库迁移或联合查询时经常引发数据顺序错乱。


















