04. 排序与分页


一、排序

  • 如果没有使用排序操作,默认情况下查询返回扽数据是按照添加数据的顺序显示的
  • 使用 ORDER BY 子句排序:
    • SELECT 字段名 FROM 表名 ORDER BY 排序字段1 ASC/DESC,排序字段2 ASC/DESC,...;
    • ASC (ascend):升序
    • DESC (descend):降序
    • 如果在 ORDER BY 后没有显示的指明排序的方式,则默认按升序排列
  • 可以使用列的别名进行排序
  • 可以使用不在SELECT列表中的列排序
  • 在对多列进行排序的时候,首先排序的第一列必须有相同的列值,才会对第二列进行排序。如果第一列数据中所有值都是唯一的,将不再对第二列进行排序。
-- 按照salary从高到低的顺序显示员工信息
SELECT employee_id,last_name,salary FROM employees ORDER BY salary DESC;

-- 按照salary从低到高的顺序显示员工信息
SELECT employee_id,last_name,salary FROM employees ORDER BY salary ASC;

-- 按照年工资从低到高的顺序显示员工信息
SELECT employee_id,last_name,salary,salary*12*(1+IFNULL(commission_pct,0)) AS "annual_salary" 
FROM employees 
ORDER BY annual_salary;

-- 按照年工资从低到高的顺序显示员工信息
SELECT employee_id,last_name,salary,salary*12*(1+IFNULL(commission_pct,0)) AS "annual_salary" 
FROM employees 
ORDER BY annual_salary ASC;

SELECT employee_id,last_name,salary 
FROM employees 
WHERE department_id IN (50,60,70) 
ORDER BY department_id DESC;

-- 二级排序
-- 显示员工信息,按照department_id的降序排列,salary的升序排列
SELECT employee_id,last_name,salary,department_id
FROM employees 
ORDER BY department_id DESC,salary ASC;

二、分页

??在不同的 DBMS 中使用的关键字可能不同。在 MySQL、PostgreSQL、MariaDB 和 SQLite 中使用 LIMIT 关键字,而且需要放到 SELECT 语句的最后面。

  • 如果是SQL Seriver 和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;

2.1、MySQL中分页显示

  • MySQL 使用 LIMIT 分页
    • SELECT 字段名 FROM 表名 LIMIT 偏移量,条目数;
    • 当偏移量等于0时,偏移量可以省略
  • 分页显式公式:每页显示pageSize条记录,此时显示第pageNo页
    • LIMIT (pageNo - 1) * pageSize, pageSize;
  • MySQL 8.0 新特性:
    • LIMIT 条目数 OFFSET 偏移量
-- 每页显示20条记录,此时显示第1页
SELECT employee_id,last_name,salary FROM employees LIMIT 0,20;

-- 每页显示20条记录,此时显示第2页
SELECT employee_id,last_name,salary FROM employees LIMIT 20,20;

-- 每页显示20条记录,此时显示第3页
SELECT employee_id,last_name,salary FROM employees LIMIT 40,20;

-- "LIMIT 0,条目数" 等价于 "LIMIT 条目数"
SELECT employee_id,last_name,salary 
FROM employees 
WHERE salary > 6000 
ORDER BY salary DESC
LIMIT 10;

-- MySQL8.0新特性:LIMIT... OFFSET...
SELECT employee_id,last_name,salary FROM employees LIMIT 2 OFFSET 31;

-- 查询员工表中工资最高的员工信息
SELECT employee_id,last_name,salary FROM employees ORDER BY salary DESC LIMIT 1;

三、练习题

-- 1. 查询员工的姓名和部门号和年薪,按年薪降序,按姓名升序显示 
SELECT last_name,department_id,salary*(1+IFNULL(commission_pct,0))*12 AS "annual_salary"
FROM employees
ORDER BY annual_salary DESC,last_name;

-- 2. 选择工资不在 8000 到 17000 的员工的姓名和工资,按工资降序,显示第21到40位置的数据 
SELECT last_name,salary
FROM employees 
WHERE salary NOT BETWEEN 8000 AND 17000
ORDER BY salary DESC
LIMIT 20,20;

-- 3. 查询邮箱中包含 e 的员工信息,并先按邮箱的字节数降序,再按部门号升序
SELECT employee_id,last_name,email,salary
FROM employees
WHERE email LIKE '%e%'
ORDER BY LENGTH(email) DESC,department_id ASC;