写在前面的话( •̀ .̫ •́ )✧
即将学习数据库系统的课程,此文为预习与自学,自学配套课程链接为:MySQL数据库入门到大牛,mysql安装到优化,百科全书级,全网天花板_哔哩哔哩_bilibili 时间不够可以不看,前五章内容都比较简单,纯看笔记也能学会。
本文主要内容是学习sql排序与分页,难易程度:简单,练习前需要先导入使用到的的数据库,使用的MySQL数据库服务器管理和开发工具是Navicat。
所使用的数据库,文件比较小,无需转存直接下载就🆗:点击下载数据库文件
文章目录
05章:排序与分页
1. 排序数据
1.1 排序规则
如果没有使用排序操作,默认情况下查询返回的数据是按照添加数据的顺序显示的
- 使用 ORDER BY 子句排序:
- 使用order by对查询到的数据进行排序操作(默认升序)
- ASC(ascend): 升序
- DESC(descend):降序
- 强调格式:WHERE需要在FROM后,ORDER BY之前使用
SELECT employee_id,salary
FROM employees
WHERE department_id IN (50,60,70)
ORDER BY department_id DESC;
1.2 单列排序
举第1个栗子:
#按照salary从高到低的顺序显示员工信息
SELECT employee_id,last_name,salary
FROM employees
ORDER BY salary DESC;
查询结果如下:
举第2个栗子:
#按照salary从低到高的顺序显示员工信息
SELECT employee_id,last_name,salary
FROM employees
-- ORDER BY salary;
ORDER BY salary ASC;
查询结果如下:
举第3个栗子:
我们可以使用列的别名,进行排序。
#按照年收入从低到高的顺序显示员工的编号以及工资、年工资
SELECT employee_id,salary,salary * 12 annual_sal
FROM employees
ORDER BY annual_sal;
查询结果如下:
注意:列的别名只能在ORDER BY中使用,不能在WHERE中使用
#以下是错误的
-- SELECT employee_id,salary,salary * 12 annual_sal
-- FROM employees
-- WHERE annual_sal > 81600;
1.3 多列排序
#显示员工信息,先按照department_id的降序排列,department_id相同时按照salary的升序排列
SELECT employee_id,salary,department_id
FROM employees
ORDER BY department_id DESC,salary ASC;
查询结果如下:
- 可以使用不在SELECT列表中的列排序。
- 在对多列进行排序的时候,首先排序的第一列必须有相同的列值,才会对第二列进行排序。如果第一列数据中所有值都是唯一的,将不再对第二列进行排序。
2. 分页
2.1 背景
- 背景1:查询返回的记录过多时,直接查看全部数据会非常不方便,因此需要通过分页查询来逐步查看数据。
- 背景2:当表中有 4 条数据时,如果只想查看第 2 和第 3 条记录,需要使用分页查询来精确控制返回的数据。
2.2 实现规则
- 分页原理:分页显示的核心是将数据库中的结果集分成若干段,每次只显示所需的部分数据。
- MySQL 使用
LIMIT
实现分页 - LIMIT格式:
LIMIT 位置偏移量,条目数
- 结构:
"LIMIT 0,条目数"等价于"LIMIT 条目数"
位置偏移量:指示从哪一行开始显示,是一个可选参数。如果不指定,默认从表中的第一条记录开始(第 1 条记录的偏移量是 0,依此类推)。
行数:指示返回的记录条数。
- 分页公式:
显示第 pageNumber
页,每页显示 pageSize
条记录:
SELECT * FROM table
LIMIT (pageNumber - 1) * pageSize, pageSize;
举几个栗子:
#需求1:每页显示20条记录,此时显示第一页(1-20)
SELECT * FROM 表名 LIMIT 0,20;
或者
SELECT * FROM 表名 LIMIT 20;
#需求2:每页显示20条记录,此时显示第二页(21-40)
SELECT * FROM 表名 LIMIT 20,20;
#需求3:每页显示20条记录,此时显示第三页(41-60)
SELECT * FROM 表名 LIMIT 40,20;
2.3 声明顺序
WHERE … ORDER BY … LIMIT 声明顺序如下:
SELECT employee_id,last_name,salary
FROM employees
WHERE salary > 6000
ORDER BY salary DESC
LIMIT 10;
注意:
LIMIT
子句必须放在整个SELECT
语句的最后!
2.4 MySQL 8.0 新特性:LIMIT … OFFSET …
LIMIT
格式:LIMIT 条目数 OFFSET 位置偏移量
- 每页显示
pageSize
条记录,显示第pageNumber
页,公式如下:
LIMIT pageSize OFFSET (pageNumber - 1) * pageSize
举个栗子:
#表里有107条数据,只显示第32、33条数据
SELECT employee_id, last_name
FROM employees
-- LIMIT 31,2;
LIMIT 2 OFFSET 31;
查询结果如下:
3. 查询分页语句练习
3.1 题目及要求
-
查询员工的姓名和部门号和年薪,按年薪降序,按姓名升序显示
要求显示如下:有107条数据
-
选择工资不在 8000到17000 的员工的姓名和工资,按工资降序,显示第21到40位置的数据
要求显示如下:第一条last_name为Ernst
-
查询邮箱中包含e的员工信息,并先按邮箱的字节数降序,再按部门号升序
要求显示如下:有47条数据
3.2 答案
#1.查询员工的姓名和部门号和年薪,按年薪降序,按姓名升序显示(107条记录)
SELECT last_name,department_id,salary * 12 annual_sal
FROM employees
ORDER BY annual_sal DESC,last_name ASC;
#2.选择工资不在 8000到17000 的员工的姓名和工资,按工资降序,显示第21到40位置的数据(第一条last_name为Ernst)
SELECT last_name,department_id,salary
FROM employees
WHERE salary NOT BETWEEN 8000 AND 17000
ORDER BY salary DESC
LIMIT 20,20;
#3.查询邮箱中包含e的员工信息,并先按邮箱的字节数降序,再按部门号升序(47条记录)
SELECT employee_id,last_name,department_id,email
FROM employees
-- WHERE email LIKE '%e%'
WHERE email REGEXP '[e]'
ORDER BY LENGTH(email) DESC,department_id ASC;
4. 拓展
在不同的 DBMS 中使用的关键字可能不同。在 MySQL、PostgreSQL、MariaDB 和 SQLite 中使用 LIMIT 关键字,而且需要放到 SELECT 语句的最后面。
- 如果是 SQL Server 和 Access,需要使用
TOP
关键字,比如:
SELECT TOP 5 name, hp_max FROM heros ORDER BY hp_max DESC
- 如果是 DB2,使用
FETCH FIRST 5 ROWS ONLY
这样的关键字:
SELECT name, hp_max FROM heros ORDER BY hp_max DESC FETCH FIRST 5 ROWS ONLY
- 如果是 Oracle,你需要基于
ROWNUM
来统计行数:
SELECT rownum,last_name,salary FROM employees WHERE rownum < 5 ORDER BY salary DESC;
需要说明的是,这条语句是先取出来前 5 条数据行,然后再按照 hp_max 从高到低的顺序进行排序。但这样产生的结果和上述方法的并不一样。我会在后面讲到子查询,你可以使用
SELECT rownum, last_name,salary
FROM (
SELECT last_name,salary
FROM employees
ORDER BY salary DESC)
WHERE rownum < 10;
得到与上述方法一致的结果。