SQL基础入门③ | 排序篇
0 序言
本文将详细讲解MySQL中排序与分页的操作方法,包括排序规则、单列与多列排序,以及分页的实现原理、格式和不同数据库的分页方式。
通过学习,你能掌握如何对查询结果进行有序展示和分段查看,使用MySQL语句灵活处理数据。
1 排序数据
在查询数据时,默认结果是无序
的,使用排序功能可以按指定规则整理结果,方便查看和分析。
1.1 排序规则
1.1.1 排序关键字
- ASC(ascend):表示
升序
,即从大到小排列,是默认排序方式。 - DESC(descend):表示
降序
,即从大到小排列。
1.1.2 排序子句位置
ORDER BY子句需放在SELECT语句的结尾,用于指定排序的依据。
这一点需要注意一下!!
1.2 单列排序
1.2.1 升序排序
以员工表(employees)为例,按入职日期(hire_date)升序排列:
SELECT last_name, job_id, department_id, hire_date
FROM employees
ORDER BY hire_date;
结果会按入职日期从早到晚
显示,最早入职的员工排在前面。
1.2.2 降序排序
同样以员工表为例,按入职日期(hire_date)降序排列:
SELECT last_name, job_id, department_id, hire_date
FROM employees
ORDER BY hire_date DESC;
结果会按入职日期从晚到早显示,最晚入职的员工排在前面。
1.2.3 基于计算结果排序
可以对查询中计算得到的结果进行排序,例如按年薪(salary*12)
升序排列:
SELECT employee_id, last_name, salary*12 annsal
FROM employees
ORDER BY annsal;
此时会根据计算出的年薪值从小到大排序。
1.3 多列排序
1.3.1 排序规则
当需要按多个列进行排序时,先按第一列排序,只有当第一列的值相同时
,才会按第二列排序
。
如果第一列的所有值都是唯一的,则不会对第二列进行排序。
1.3.2 具体示例
按部门ID(department_id)升序、工资(salary)降序排列员工信息:
SELECT last_name, department_id, salary
FROM employees
ORDER BY department_id, salary DESC;
结果中,先按部门ID从小到大分组,同一部门内的员工再按工资从高到低排列。
1.3.3 注意事项
可以使用不在SELECT列表中的列进行排序
,只要该列存在于数据表中即可。
举个例子,
SELECT last_name, salary
FROM employees
ORDER BY department_id;
SELECT 列表中只包含last_name和salary,但排序时使用了department_id列(该列存在于employees表中),即通过表中存在但未在查询结果中显示的列进行排序.
2 分页
由于在某些情况下,查询返回的记录太多,查看不便,需要分页查询来分段展示。
表中有多条数据,只想查看其中某一段的记录,如第2、3条数据。
这个时候,使用分页就能够提高效率。
当查询结果记录较多时,分页可以将结果分段显示
,
便于查看和处理,同时减少数据传输量,提高查询效率。
2.1 实现规则
2.1.1 分页原理
分页显示是将数据库中的结果集按一定数量分段,每次只显示一段数据,需要指定起始位置和显示的记录条数。
2.1.2 MySQL中分页格式
使用LIMIT子句实现分页,格式为:LIMIT [位置偏移量,] 行数
- 位置偏移量:表示从第几条记录开始
(起始位置从0开始,即第一条记录的偏移量为0,第二条为1,以此类推)。
- 行数:指示返回的记录条数。
2.1.3 示例
- 前10条记录:
SELECT * FROM 表名 LIMIT 0,10;
或简化为:
SELECT * FROM 表名 LIMIT 10;
不写的话默认就是从0,也就是开头开始。
- 第11至20条记录:
SELECT * FROM 表名 LIMIT 10,10;
- 第21至30条记录:
SELECT * FROM 表名 LIMIT 20,10;
注意,不是闭区间,这个要注意一下。
我这里演示一下,加深理解。
SELECT employee_id, last_name FROM employees LIMIT 10;
SELECT employee_id, last_name FROM employees LIMIT 10,10;
2.1.4 MySQL 8.0中的分页方式
可以使用LIMIT 行数 OFFSET 位置偏移量
,
例如获取从第5条记录开始后面的3条记录:
LIMIT 3 OFFSET 4;
这与LIMIT 4,3;
返回的结果相同。
其中OFFSET 4
表示从第 5 条记录开始(偏移量从 0 计数,4 即跳过前 4 条),LIMIT 3
表示取 3 条记录,最终会返回第 5、6、7 条记录。
这种写法与 LIMIT 4,3
效果完全相同,
只是将偏移量和行数的顺序通过 “OFFSET” 关键字明确区分,
本质上,就是 跳过多少行后取多少行
的逻辑。
2.1.5 分页公式
若要显示第PageNo页,每页显示PageSize条记录,分页公式为:
SELECT * FROM table
LIMIT (PageNo - 1)*PageSize, PageSize;
例如以下例子:
SELECT * FROM employees
LIMIT (3 - 1)*5, 5;
计算后即 LIMIT 10, 5,表示从第 11 条记录开始(跳过前 10 条),获取 5 条记录,对应第 3 页的数据。
2.1.6 注意事项
LIMIT子句必须放在整个SELECT语句的最后。
2.1.7 LIMIT的优势
- 约束返回结果的数量可以
减少数据表的网络传输量
。 提升查询效率
,例如知道返回结果只有1条时,使用LIMIT 1,SELECT语句只需检索到一条符合条件的记录即可返回,无需扫描完整的表
。
2.2 拓展
不同的DBMS实现分页的关键字不同,例如说:
- DB2:使用FETCH FIRST 行数 ROWS ONLY关键字,例如:
SELECT name, hp_max FROM heros ORDER BY hp_max DESC FETCH FIRST 5 ROWS ONLY;
- MySQL、PostgreSQL、MariaDB和SQLite:使用LIMIT关键字,放在SELECT语句最后。
- SQL Server和Access:使用TOP关键字,例如:
SELECT TOP 5 name, hp_max FROM heros ORDER BY hp_max DESC;
- Oracle:基于ROWNUM来统计行数,例如:
SELECT rownum, last_name, salary FROM employees WHERE rownum < 5 ORDER BY salary DESC;
但此语句是先取前5条数据再排序,若要先排序再取前N条,可使用子查询:
SELECT last_name, salary
FROM (SELECT last_name, salary FROM employees ORDER BY salary DESC)
WHERE rownum < 10;
3 小结
本文介绍了MySQL中排序和分页的相关知识。
排序方面
讲解了升序(ASC)、降序(DESC)的使用,以及单列排序、多列排序的规则和示例,还提到了可使用非SELECT列表中的列排序。
分页方面
说明了MySQL中LIMIT子句的使用格式、分页公式、注意事项,同时拓展了不同DBMS的分页方式。
希望这些内容,能让读者更灵活地处理查询结果,满足不同的SQL需求。