摘要:MySQL的limit除了返回需要的数据外,还常常和order by配合起来进行分页。
在实际业务中,常常有需要返回特定部分数据的场景,比如
- 找出工资最高的前两名同事
- 找出公司第二名雇佣的员工
- …
Oracle通过子句order by配合rownum实现,SQL Server有top,MySQL就是通过limit了。我们先来看看limit的语法:
SELECT ... [LIMIT {[offset,] row_count | row_count OFFSET offset}] 其中offset表示记录的起始偏移量,row_count表示显示的行数。默认情况下,起始偏移量为0,只需要写记录行数就行,这时,实际显示的就是前n条记录。
例如,找出工资最高的前两名同事
root@database-one 21:21: [gftest]> select * from emp; +--------+------+---------+------------+--------+ | ename | age | sal | hiredate | deptno | +--------+------+---------+------------+--------+ | 郭军 | 27 | 8400.00 | 2019-12-08 | 10 | | 刘杰 | 30 | 9100.00 | 2018-04-09 | 10 | | 王艳 | 24 | 6000.00 | 2020-01-05 | 20 | | 马丽 | 26 | 7200.00 | 2018-07-06 | 30 | | 肖伟 | 29 | 8700.00 | 2017-05-28 | 30 | +--------+------+---------+------------+--------+ 5 rows in set (0.01 sec) root@database-one 21:21: [gftest]> select * from emp order by sal desc limit 2; +--------+------+---------+------------+--------+ | ename | age | sal | hiredate | deptno | +--------+------+---------+------------+--------+ | 刘杰 | 30 | 9100.00 | 2018-04-09 | 10 | | 肖伟 | 29 | 8700.00 | 2017-05-28 | 30 | +--------+------+---------+------------+--------+ 2 rows in set (0.00 sec)
找出公司第二名雇佣的员工
root@database-one 21:21: [gftest]> select * from emp order by hiredate; +--------+------+---------+------------+--------+ | ename | age | sal | hiredate | deptno | +--------+------+---------+------------+--------+ | 肖伟 | 29 | 8700.00 | 2017-05-28 | 30 | | 刘杰 | 30 | 9100.00 | 2018-04-09 | 10 | | 马丽 | 26 | 7200.00 | 2018-07-06 | 30 | | 郭军 | 27 | 8400.00 | 2019-12-08 | 10 | | 王艳 | 24 | 6000.00 | 2020-01-05 | 20 | +--------+------+---------+------------+--------+ 5 rows in set (0.00 sec) root@database-one 21:22: [gftest]> select * from emp order by hiredate limit 1,1; +--------+------+---------+------------+--------+ | ename | age | sal | hiredate | deptno | +--------+------+---------+------------+--------+ | 刘杰 | 30 | 9100.00 | 2018-04-09 | 10 | +--------+------+---------+------------+--------+ 1 row in set (0.00 sec)
在软件开发领域,limit还有个非常多的使用场景,就是和order by配合起来进行分页。
比如一个表中有很多数据,软件页面显示时只显示10条数据,当用户点击下一页时再显示接下来的10条数据,跳转到特定的页只显示那个页对应的数据。
我们先构造一张新表emp_copy,放些数据
root@database-one 22:00:  [gftest]> 
root@database-one 22:00:  [gftest]> CREATE TABLE `emp_copy` (
    ->  `eno` int auto_increment not null,
    ->  `ename` varchar(10) DEFAULT NULL,
    ->  `age` int(11) DEFAULT NULL,
    ->  `sal` decimal(10,2) DEFAULT NULL,
    ->  `hiredate` date DEFAULT NULL,
    ->  `deptno` int(2) DEFAULT NULL,
    ->  primary key(eno)
    ->  ) ENGINE=InnoDB DEFAULT CHARSET=utf8
    ->  ;
Query OK, 0 rows affected (3.01 sec)
root@database-one 22:00:  [gftest]> insert into emp_copy(ename,age,sal,hiredate,deptno) select * from emp;
Query OK, 5 rows affected (1.01 sec)
Records: 5  Duplicates: 0  Warnings: 0
root@database-one 22:00:  [gftest]> insert into emp_copy(ename,age,sal,hiredate,deptno) select ename,age,sal,hiredate,deptno from emp_copy;
Query OK, 5 rows affected (0.23 sec)
Records: 5  Duplicates: 0  Warnings: 0
root@database-one 22:01:  [gftest]> insert into emp_copy(ename,age,sal,hiredate,deptno) select ename,age,sal,hiredate,deptno from emp_copy;
Query OK, 10 rows affected (0.20 sec)
Records: 10  Duplicates: 0  Warnings: 0
root@database-one 22:01:  [gftest]> insert into emp_copy(ename,age,sal,hiredate,deptno) select ename,age,sal,hiredate,deptno from emp_copy;
Query OK, 20 rows affected (0.03 sec)
Records: 20  Duplicates: 0  Warnings: 0
root@database-one 22:01:  [gftest]> commit;
Query OK, 0 rows affected (0.00 sec)
root@database-one 22:01:  [gftest]> select * from emp_copy;
+-----+--------+------+---------+------------+--------+
| eno | ename  | age  | sal     | hiredate   | deptno |
+-----+--------+------+---------+------------+--------+
|   1 | 郭军   |   27 | 8400.00 | 2019-12-08 |     10 |
|   2 | 刘杰   |   30 | 9100.00 | 2018-04-09 |     10 |
|   3 | 王艳   |   24 | 6000.00 | 2020-01-05 |     20 |
|   4 | 马丽   |   26 | 7200.00 | 2018-07-06 |     30 |
|   5 | 肖伟   |   29 | 8700.00 | 2017-05-28 |     30 |
|   8 | 郭军   |   27 | 8400.00 | 2019-12-08 |     10 |
|   9 | 刘杰   |   30 | 9100.00 | 2018-04-09 |     10 |
|  10 | 王艳   |   24 | 6000.00 | 2020-01-05 |     20 |
|  11 | 马丽   |   26 | 7200.00 | 2018-07-06 |     30 |
|  12 | 肖伟   |   29 | 8700.00 | 2017-05-28 |     30 |
|  15 | 郭军   |   27 | 8400.00 | 2019-12-08 |     10 |
|  16 | 刘杰   |   30 | 9100.00 | 2018-04-09 |     10 |
|  17 | 王艳   |   24 | 6000.00 | 2020-01-05 |     20 |
|  18 | 马丽   |   26 | 7200.00 | 2018-07-06 |     30 |
|  19 | 肖伟   |   29 | 8700.00 | 2017-05-28 |     30 |
|  20 | 郭军   |   27 | 8400.00 | 2019-12-08 |     10 |
|  21 | 刘杰   |   30 | 9100.00 | 2018-04-09 |     10 |
|  22 | 王艳   |   24 | 6000.00 | 2020-01-05 |     20 |
|  23 | 马丽   |   26 | 7200.00 | 2018-07-06 |     30 |
|  24 | 肖伟   |   29 | 8700.00 | 2017-05-28 |     30 |
|  30 | 郭军   |   27 | 8400.00 | 2019-12-08 |     10 |
|  31 | 刘杰   |   30 | 9100.00 | 2018-04-09 |     10 |
|  32 | 王艳   |   24 | 6000.00 | 2020-01-05 |     20 |
|  33 | 马丽   |   26 | 7200.00 | 2018-07-06 |     30 |
|  34 | 肖伟   |   29 | 8700.00 | 2017-05-28 |     30 |
|  35 | 郭军   |   27 | 8400.00 | 2019-12-08 |     10 |
|  36 | 刘杰   |   30 | 9100.00 | 2018-04-09 |     10 |
|  37 | 王艳   |   24 | 6000.00 | 2020-01-05 |     20 |
|  38 | 马丽   |   26 | 7200.00 | 2018-07-06 |     30 |
|  39 | 肖伟   |   29 | 8700.00 | 2017-05-28 |     30 |
|  40 | 郭军   |   27 | 8400.00 | 2019-12-08 |     10 |
|  41 | 刘杰   |   30 | 9100.00 | 2018-04-09 |     10 |
|  42 | 王艳   |   24 | 6000.00 | 2020-01-05 |     20 |
|  43 | 马丽   |   26 | 7200.00 | 2018-07-06 |     30 |
|  44 | 肖伟   |   29 | 8700.00 | 2017-05-28 |     30 |
|  45 | 郭军   |   27 | 8400.00 | 2019-12-08 |     10 |
|  46 | 刘杰   |   30 | 9100.00 | 2018-04-09 |     10 |
|  47 | 王艳   |   24 | 6000.00 | 2020-01-05 |     20 |
|  48 | 马丽   |   26 | 7200.00 | 2018-07-06 |     30 |
|  49 | 肖伟   |   29 | 8700.00 | 2017-05-28 |     30 |
+-----+--------+------+---------+------------+--------+
40 rows in set (0.02 sec)
root@database-one 22:01:  [gftest]>
细心的同学可能注意到自增列的序号有跳号,这个跟MySQL的原理有关,是因为批量插入数据造成的,后面再抽时间详细说明。
按eno降序分页显示数据
select * from emp_copy order by eno desc limit (N-1)*M,M;
N代表页数,M代表每页显示的记录数
假设10行为一页,显示第1页
root@database-one 22:06: [gftest]> select * from emp_copy order by eno desc limit 0,10; +-----+--------+------+---------+------------+--------+ | eno | ename | age | sal | hiredate | deptno | +-----+--------+------+---------+------------+--------+ | 49 | 肖伟 | 29 | 8700.00 | 2017-05-28 | 30 | | 48 | 马丽 | 26 | 7200.00 | 2018-07-06 | 30 | | 47 | 王艳 | 24 | 6000.00 | 2020-01-05 | 20 | | 46 | 刘杰 | 30 | 9100.00 | 2018-04-09 | 10 | | 45 | 郭军 | 27 | 8400.00 | 2019-12-08 | 10 | | 44 | 肖伟 | 29 | 8700.00 | 2017-05-28 | 30 | | 43 | 马丽 | 26 | 7200.00 | 2018-07-06 | 30 | | 42 | 王艳 | 24 | 6000.00 | 2020-01-05 | 20 | | 41 | 刘杰 | 30 | 9100.00 | 2018-04-09 | 10 | | 40 | 郭军 | 27 | 8400.00 | 2019-12-08 | 10 | +-----+--------+------+---------+------------+--------+ 10 rows in set (0.01 sec)
显示第2页
root@database-one 22:12: [gftest]> select * from emp_copy order by eno desc limit 10,10; +-----+--------+------+---------+------------+--------+ | eno | ename | age | sal | hiredate | deptno | +-----+--------+------+---------+------------+--------+ | 39 | 肖伟 | 29 | 8700.00 | 2017-05-28 | 30 | | 38 | 马丽 | 26 | 7200.00 | 2018-07-06 | 30 | | 37 | 王艳 | 24 | 6000.00 | 2020-01-05 | 20 | | 36 | 刘杰 | 30 | 9100.00 | 2018-04-09 | 10 | | 35 | 郭军 | 27 | 8400.00 | 2019-12-08 | 10 | | 34 | 肖伟 | 29 | 8700.00 | 2017-05-28 | 30 | | 33 | 马丽 | 26 | 7200.00 | 2018-07-06 | 30 | | 32 | 王艳 | 24 | 6000.00 | 2020-01-05 | 20 | | 31 | 刘杰 | 30 | 9100.00 | 2018-04-09 | 10 | | 30 | 郭军 | 27 | 8400.00 | 2019-12-08 | 10 | +-----+--------+------+---------+------------+--------+ 10 rows in set (0.02 sec)
显示第4页
root@database-one 22:12:  [gftest]> select * from emp_copy order by eno desc limit 30,10;
+-----+--------+------+---------+------------+--------+
| eno | ename  | age  | sal     | hiredate   | deptno |
+-----+--------+------+---------+------------+--------+
|  12 | 肖伟   |   29 | 8700.00 | 2017-05-28 |     30 |
|  11 | 马丽   |   26 | 7200.00 | 2018-07-06 |     30 |
|  10 | 王艳   |   24 | 6000.00 | 2020-01-05 |     20 |
|   9 | 刘杰   |   30 | 9100.00 | 2018-04-09 |     10 |
|   8 | 郭军   |   27 | 8400.00 | 2019-12-08 |     10 |
|   5 | 肖伟   |   29 | 8700.00 | 2017-05-28 |     30 |
|   4 | 马丽   |   26 | 7200.00 | 2018-07-06 |     30 |
|   3 | 王艳   |   24 | 6000.00 | 2020-01-05 |     20 |
|   2 | 刘杰   |   30 | 9100.00 | 2018-04-09 |     10 |
|   1 | 郭军   |   27 | 8400.00 | 2019-12-08 |     10 |
+-----+--------+------+---------+------------+--------+
10 rows in set (0.01 sec)© 2020, morinson. 版权所有. 欢迎转载,但请保留作者及出处。