sql 里面 order by 子句如果没有手动写 asc 或者 desc,默认就是升序,也就是从小到大排列,数字类型会按照数值从小到大,文本类型会按照字符编码顺序从小到大,日期类型会按照时间从早到晚,这个规则在 MySQL sqlite3 SQL Server 绝大多数主流关系型数据库里面都是统一的,很多新手写 order by 的时候经常忘记标注 asc,以为数据库会随机排序,其实数据库会自动套用升序逻辑,这里还要区分一个容易混淆的点,如果不写 order by,数据库返回的数据顺序是不确定的,不能默认认为是主键升序,这个是两个完全不同的概念,没有 order by 就不存在排序规则,数据库会按照存储或者执行计划返回行,不保证每次查询顺序一致,学习排序的时候一定要把这两个概念分开,避免业务代码出现隐性 bug。
排序关键字说明
asc 全称 ascending,含义升序,从小到大,属于默认值,可以省略不写
desc 全称 descending,含义降序,从大到小,必须手动写出来,不写就不会生效
排序可以作用在数字,字符串,日期,时间,布尔类型,不同类型排序的判定逻辑不一样,数字直接比较数值,字符串是逐字符对比编码,日期是对比时间先后。
基础示例
单字段升序 省略 asc
select id name from student order by age
等价写法
select id name from student order by age asc
单字段降序
select id name from student order by age desc
多字段混合排序
select id name from student order by class asc age desc
含义是先按照班级升序,班级数值相同的记录,再按照年龄降序,多字段排序是从左往右依次生效,前面字段相同才会启用后面字段排序规则。
排序规则对照表
| 写法 | 排序方向 | 是否需要手动书写 |
|---|---|---|
| order by 字段 | 升序 | asc 可以省略 |
| order by 字段 asc | 升序 | 显式声明 |
| order by 字段 desc | 降序 | 必须手动写 desc |
深度注意要点
第一点 null 值排序差异,不同数据库对 null 默认排序位置不一样,MySQL 里面升序的时候 null 排在最前面,Oracle 升序 null 默认排在末尾,跨数据库迁移的时候这个差异很容易踩坑,如果业务对 null 位置有严格要求,需要额外指定 nulls first 或者 nulls last,但是这个语法不是所有数据库都支持,sqlite3 就不支持该语法。
第二点 字符串排序区分大小写,部分数据库排序的时候会区分大小写,大写字母编码小于小写字母,会出现大写排在小写前面,如果需要不区分大小写排序,需要使用转换函数处理字段。
第三点 索引和排序性能,如果 order by 字段建立索引,数据库可以直接利用索引顺序返回数据,不需要额外排序,性能更高,如果没有索引,数据库会做 filesort 额外排序,大表查询的时候会明显变慢。
第四点 不要混淆无 order by 的物理顺序,很多人误以为主键自增表,不加 order by 就一定按主键升序,这个理解错误,数据库在更新删除之后,存储页变化,执行计划改变,返回顺序可能改变,业务需要固定顺序必须写 order by。
编写排序语句操作步骤
第一步 确认业务需求,确定是从小到大升序,还是从大到小降序
第二步 如果是升序,可以省略 asc,推荐正式业务代码显式写 asc,提升代码可读性
第三步 如果是降序,必须追加 desc 关键字,不能漏掉
第四步 多字段排序的时候,依次填写每个字段对应的 asc 或者 desc
第五步 执行查询,核对排序结果,确认 null 位置是否符合业务预期
第六步 大表场景检查执行计划,确认排序是否命中索引,必要时补充索引优化
整体总结,sql 的 order by 默认排序是升序 asc,desc 降序必须手动声明,重点区分两个概念,写了 order by 才会触发默认升序,完全不写 order by 不存在默认排序,结果顺序不稳定,跨数据库还要留意 null 值排序位置的差异,业务代码推荐显式写出 asc,不要依赖默认规则,提升 SQL 可读性,减少后续维护误解。
【常见问题】
问题 1 sql 默认升序还是降序,多字段排序可以一部分升序一部分降序吗
回答 1 sql 默认升序还是降序,order by 默认是升序,多字段排序支持混合方向,每个字段可以单独指定 asc 或者 desc,不需要全部统一成升序或者降序。
问题 2 sql 默认升序还是降序,不加 order by 会默认主键升序吗
回答 1 sql 默认升序还是降序,不加 order by 并不会默认主键升序,没有 order by 的时候数据库没有排序动作,返回顺序不稳定,不能依赖默认升序规则。
问题 3 sql 默认升序还是降序,sqlite3 排序规则和 MySQL 一样吗
回答 1 sql 默认升序还是降序,sqlite3 的 order by 默认升序规则和 MySQL 保持一致,但是 null 排序细节存在差别,学习 sql 默认升序还是降序跨库使用需要留意这个差异。
问题 4 sql 默认升序还是降序,日期类型 order by 也是默认升序吗
回答 1 sql 默认升序还是降序,日期类型 order by 同样默认升序,也就是时间从早到晚排列,如果需要最新日期排在前面,就要手动加上 desc。
【免责申明】
本文内容仅作为 SQL 语法学习参考,不同数据库版本对 null 排序等细节存在差异,业务开发请以目标数据库官方文档为准,因依赖默认排序产生的数据顺序错误由使用者自行承担。


