新闻资讯

新闻资讯 媒体报道

MySQL学习,详解分页查询(limit)

编辑:013     时间:2021-10-16

limit介绍

limit⽤来限制select查询返回的⾏数,常⽤于分页等操作。

语法:

select 列 from 表 limit [offset,] count;

说明:

offset:表⽰偏移量,通俗点讲就是跳过多少⾏,offset可以省略,默认为0,表

⽰跳过0⾏;范围:[0,+∞)。

count:跳过offset⾏之后开始取数据,取count⾏记录;范围:[0,+∞)。

limit中offset和count的值不能⽤表达式。

下⾯我们列⼀些常⽤的⽰例来加深理解。

获取前n⾏记录

select 列 from 表 limit 0,n;

或者

select 列 from 表 limit n;

⽰例,获取订单的前2条记录,如下:

mysql> create table t_order(

 -> id int not null auto_increment comment '订单编号',

 -> price decimal(10,2) not null default 0 comment '订单⾦额',

 -> primary key(id)

 -> )comment '订单表';

Query OK, 0 rows affected (0.01 sec)

mysql> insert into t_order (price) values (88.95),(100.68),(500),

(300),(20.88),(200.5);Query OK, 6 rows affected (0.01 sec)

Records: 6 Duplicates: 0 Warnings: 0

mysql> select * from t_order;

+----+--------+

| id | price |

+----+--------+

| 1 | 88.95 |

| 2 | 100.68 |

| 3 | 500.00 |

| 4 | 300.00 |

| 5 | 20.88 |

| 6 | 200.50 |

+----+--------+

6 rows in set (0.00 sec)

mysql> select a.id 订单编号,a.price 订单⾦额 from t_order a limit 2;

+--------------+--------------+

| 订单编号 | 订单⾦额 |

+--------------+--------------+

| 1 | 88.95 |

| 2 | 100.68 |

+--------------+--------------+

2 rows in set (0.00 sec)

 

mysql> select a.id 订单编号,a.price 订单⾦额 from t_order a limit 0,2;

+--------------+--------------+

| 订单编号 | 订单⾦额 |

+--------------+--------------+

| 1 | 88.95 |

| 2 | 100.68 |

+--------------+--------------+

2 rows in set (0.00 sec)

获取最⼤的⼀条记录

我们需要获取订单⾦额最⼤的⼀条记录,可以这么做:先按照⾦额降序,然后取第⼀条记

录,如下:mysql> select a.id 订单编号,a.price 订单⾦额 from t_order a order by

a.price desc;

+--------------+--------------+

| 订单编号 | 订单⾦额 |

+--------------+--------------+

| 3 | 500.00 |

| 4 | 300.00 |

| 6 | 200.50 |

| 2 | 100.68 |

| 1 | 88.95 |

| 5 | 20.88 |

+--------------+--------------+

6 rows in set (0.00 sec)

mysql> select a.id 订单编号,a.price 订单⾦额 from t_order a order by 

a.price desc limit 1;

+--------------+--------------+

| 订单编号 | 订单⾦额 |

+--------------+--------------+

| 3 | 500.00 |

+--------------+--------------+

1 row in set (0.00 sec)

mysql> select a.id 订单编号,a.price 订单⾦额 from t_order a order by 

a.price desc limit 0,1;

+--------------+--------------+

| 订单编号 | 订单⾦额 |

+--------------+--------------+

| 3 | 500.00 |

+--------------+--------------+

1 row in set (0.00 sec)

获取排名第n到m的记录

我们需要先跳过n-1条记录,然后取m-n+1条记录,如下:

select 列 from 表 limit n-1,m-n+1;如:我们想获取订单⾦额最⾼的3到5名的记录,我们需要跳过2条,然后获取3条记录,

如下:

mysql> select a.id 订单编号,a.price 订单⾦额 from t_order a order by 

a.price desc;

+--------------+--------------+

| 订单编号 | 订单⾦额 |

+--------------+--------------+

| 3 | 500.00 |

| 4 | 300.00 |

| 6 | 200.50 |

| 2 | 100.68 |

| 1 | 88.95 |

| 5 | 20.88 |

+--------------+--------------+

6 rows in set (0.00 sec)

mysql> select a.id 订单编号,a.price 订单⾦额 from t_order a order by 

a.price desc limit 2,3;

+--------------+--------------+

| 订单编号 | 订单⾦额 |

+--------------+--------------+

| 6 | 200.50 |

| 2 | 100.68 |

| 1 | 88.95 |

+--------------+--------------+

3 rows in set (0.00 sec)

分⻚查询

开发过程中,分页我们经常使⽤,分页⼀般有2个参数:

page:表⽰第⼏页,从1开始,范围[1,+∞)

pageSize:每页显⽰多少条记录,范围[1,+∞)

如:page = 2,pageSize = 10,表⽰获取第2页10条数据。

我们使⽤limit实现分页,语法如下:select 列 from 表名 limit (page - 1) * pageSize,pageSize;

需求:我们按照订单⾦额降序,每页显⽰2条,依次获取所有订单数据、第1页、第2页、

第3页数据,如下:

mysql> select a.id 订单编号,a.price 订单⾦额 from t_order a order by 

a.price desc;

+--------------+--------------+

| 订单编号 | 订单⾦额 |

+--------------+--------------+

| 3 | 500.00 |

| 4 | 300.00 |

| 6 | 200.50 |

| 2 | 100.68 |

| 1 | 88.95 |

| 5 | 20.88 |

+--------------+--------------+

6 rows in set (0.00 sec)

mysql> select a.id 订单编号,a.price 订单⾦额 from t_order a order by 

a.price desc limit 0,2;

+--------------+--------------+

| 订单编号 | 订单⾦额 |

+--------------+--------------+

| 3 | 500.00 |

| 4 | 300.00 |

+--------------+--------------+

2 rows in set (0.00 sec)

mysql> select a.id 订单编号,a.price 订单⾦额 from t_order a order by 

a.price desc limit 2,2;

+--------------+--------------+

| 订单编号 | 订单⾦额 |

+--------------+--------------+

| 6 | 200.50 |

| 2 | 100.68 |

+--------------+--------------+

2 rows in set (0.00 sec)mysql> select a.id 订单编号,a.price 订单⾦额 from t_order a order by 

a.price desc limit 4,2;

+--------------+--------------+

| 订单编号 | 订单⾦额 |

+--------------+--------------+

| 1 | 88.95 |

| 5 | 20.88 |

+--------------+--------------+

2 rows in set (0.00 sec)

避免踩坑

limit中不能使⽤表达式

mysql> select * from t_order where limit 1,4+1;

ERROR 1064 (42000): You have an error in your SQL syntax; check the 

manual that corresponds to your MySQL server version for the right 

syntax to use near 'limit 1,4+1' at line 1

mysql> select * from t_order where limit 1+0;

ERROR 1064 (42000): You have an error in your SQL syntax; check the 

manual that corresponds to your MySQL server version for the right 

syntax to use near 'limit 1+0' at line 1

mysql>

结论:limit后⾯只能够跟明确的数字。

limit后⾯的2个数字不能为负数

mysql> select * from t_order where limit -1;

ERROR 1064 (42000): You have an error in your SQL syntax; check the 

manual that corresponds to your MySQL server version for the right 

syntax to use near 'limit -1' at line 1

mysql> select * from t_order where limit 0,-1;

ERROR 1064 (42000): You have an error in your SQL syntax; check the 

manual that corresponds to your MySQL server version for the right 

syntax to use near 'limit 0,-1' at line 1

mysql> select * from t_order where limit -1,-1;

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right 

syntax to use near 'limit -1,-1' at line 1

排序分⻚存在的坑

准备数据:

mysql> insert into test1 (b) values (1),(2),(3),(4),(2),(2),(2),(2);

Query OK, 8 rows affected (0.01 sec)

Records: 8 Duplicates: 0 Warnings: 0

mysql> select * from test1;

+---+---+

| a | b |

+---+---+

| 1 | 1 |

| 2 | 2 |

| 3 | 3 |

| 4 | 4 |

| 5 | 2 |

| 6 | 2 |

| 7 | 2 |

| 8 | 2 |

+---+---+

8 rows in set (0.00 sec)

 

mysql> select * from test1 order by b asc;

+---+---+

| a | b |

+---+---+

| 1 | 1 |

| 2 | 2 |

| 5 | 2 |

| 6 | 2 |

| 7 | 2 |

| 8 | 2 |

| 3 | 3 |

| 4 | 4 |+---+---+

8 rows in set (0.00 sec)

下⾯我们按照b升序,每页2条数据,来获取数据。

下⾯的sql依次为第1页、第2页、第3页、第4页、第5页的数据,如下:

mysql> select * from test1 order by b asc limit 0,2;

+---+---+

| a | b |

+---+---+

| 1 | 1 |

| 2 | 2 |

+---+---+

2 rows in set (0.00 sec)

mysql> select * from test1 order by b asc limit 2,2;

+---+---+

| a | b |

+---+---+

| 8 | 2 |

| 6 | 2 |

+---+---+

2 rows in set (0.00 sec)

mysql> select * from test1 order by b asc limit 4,2;

+---+---+

| a | b |

+---+---+

| 6 | 2 |

| 7 | 2 |

+---+---+

2 rows in set (0.00 sec)

mysql> select * from test1 order by b asc limit 6,2;

+---+---+

| a | b |

+---+---+

| 3 | 3 |

| 4 | 4 |

+---+---+2 rows in set (0.00 sec)

mysql> select * from test1 order by b asc limit 7,2;

+---+---+

| a | b |

+---+---+

| 4 | 4 |

+---+---+

1 row in set (0.00 sec)

上⾯有2个问题:

问题1:看⼀下第2个sql和第3个sql,分别是第2页和第3页的数据,结果出现了相同的数

据,是不是懵逼了。

问题2:整个表只有8条记录,怎么会出现第5页的数据呢,又懵逼了。

我们来分析⼀下上⾯的原因:主要是b字段存在相同的值,当排序过程中存在相同的值

时,没有其他排序规则时,mysql懵逼了,不知道怎么排序了。

就像我们上学站队⼀样,按照⾝⾼排序,那⾝⾼⼀样的时候如何排序呢?⾝⾼⼀样的就乱

排了。

建议:排序中存在相同的值时,需要再指定⼀个排序规则,通过这种排序规则不存在⼆义

性,⽐如上⾯可以再加上a降序,如下:

mysql> select * from test1 order by b asc,a desc;

+---+---+

| a | b |

+---+---+

| 1 | 1 |

| 8 | 2 |

| 7 | 2 |

| 6 | 2 |

| 5 | 2 |

| 2 | 2 |

| 3 | 3 |

| 4 | 4 |

+---+---+8 rows in set (0.00 sec)

mysql> select * from test1 order by b asc,a desc limit 0,2;

+---+---+

| a | b |

+---+---+

| 1 | 1 |

| 8 | 2 |

+---+---+

2 rows in set (0.00 sec)

mysql> select * from test1 order by b asc,a desc limit 2,2;

+---+---+

| a | b |

+---+---+

| 7 | 2 |

| 6 | 2 |

+---+---+

2 rows in set (0.00 sec)

mysql> select * from test1 order by b asc,a desc limit 4,2;

+---+---+

| a | b |

+---+---+

| 5 | 2 |

| 2 | 2 |

+---+---+

2 rows in set (0.00 sec)

mysql> select * from test1 order by b asc,a desc limit 6,2;

+---+---+

| a | b |

+---+---+

| 3 | 3 |

| 4 | 4 |

+---+---+

2 rows in set (0.00 sec)

mysql> select * from test1 order by b asc,a desc limit 8,2;

Empty set (0.00 sec)看上⾯的结果,分页数据都正常了,第5页也没有数据了。

总结

• order by ... [asc|desc]⽤于对查询结果排序,asc:升序,desc:降序,asc|desc可以省

略,默认为asc

• limit⽤来限制查询结果返回的⾏数,有2个参数(offset,count),offset:表⽰跳过

多少⾏,count:表⽰跳过offset⾏之后取count⾏

• limit中offset可以省略,默认值为0

• limit中offset count都必须⼤于等于0

• limit中offset和count的值不能⽤表达式

• 分页排序时,排序不要有⼆义性,⼆义性情况下可能会导致分页结果乱序,可以在后

⾯追加⼀个主键排序

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

回复列表

相关推荐