Mysql排序和分页(order by&limit)及存在的坑

排序查询(order by)

电商中:我们想查看今天所有成交的订单,按照交易额从高到低排序,此时我们可以使用数据库中的排序功能来完成。

排序语法:

select 字段名 from 表名 order by 字段1 [asc|desc],字段2 [asc|desc];
  • 需要排序的字段跟在order by之后;
  • asc|desc表示排序的规则,asc:升序,desc:降序,默认为asc;
  • 支持多个字段进行排序,多字段排序之间用逗号隔开。

单字段排序

mysql> create table test2(a int,b varchar(10));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into test2 values (10,'jack'),(8,'tom'),(5,'ready'),(100,'javacode');
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from test2;
+------+----------+
| a  | b    |
+------+----------+
|  10 | jack   |
|  8 | tom   |
|  5 | ready  |
| 100 | javacode |
+------+----------+
4 rows in set (0.00 sec)
mysql> select * from test2 order by a asc;
+------+----------+
| a  | b    |
+------+----------+
|  5 | ready  |
|  8 | tom   |
|  10 | jack   |
| 100 | javacode |
+------+----------+
4 rows in set (0.00 sec)
mysql> select * from test2 order by a desc;
+------+----------+
| a  | b    |
+------+----------+
| 100 | javacode |
|  10 | jack   |
|  8 | tom   |
|  5 | ready  |
+------+----------+
4 rows in set (0.00 sec)
mysql> select * from test2 order by a;
+------+----------+
| a  | b    |
+------+----------+
|  5 | ready  |
|  8 | tom   |
|  10 | jack   |
| 100 | javacode |
+------+----------+
4 rows in set (0.00 sec)

多字段排序

比如学生表,先按学生年龄降序,年龄相同时,再按学号升序,如下:

mysql> create table stu(id int not null comment '学号' primary key,age tinyint not null comment '年龄',name varchar(16) comment '姓名');
Query OK, 0 rows affected (0.01 sec)
mysql> insert into stu (id,age,name) values (1001,18,'路人甲Java'),(1005,20,'刘德华'),(1003,18,'张学友'),(1004,20,'张国荣'),(1010,19,'梁朝伟');
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from stu;
+------+-----+---------------+
| id  | age | name     |
+------+-----+---------------+
| 1001 | 18 | 路人甲Java  |
| 1003 | 18 | 张学友    |
| 1004 | 20 | 张国荣    |
| 1005 | 20 | 刘德华    |
| 1010 | 19 | 梁朝伟    |
+------+-----+---------------+
5 rows in set (0.00 sec)
mysql> select * from stu order by age desc,id asc;
+------+-----+---------------+
| id  | age | name     |
+------+-----+---------------+
| 1004 | 20 | 张国荣    |
| 1005 | 20 | 刘德华    |
| 1010 | 19 | 梁朝伟    |
| 1001 | 18 | 路人甲Java  |
| 1003 | 18 | 张学友    |
+------+-----+---------------+
5 rows in set (0.00 sec)

按别名排序

mysql> select * from stu;
+------+-----+---------------+
| id  | age | name     |
+------+-----+---------------+
| 1001 | 18 | 路人甲Java  |
| 1003 | 18 | 张学友    |
| 1004 | 20 | 张国荣    |
| 1005 | 20 | 刘德华    |
| 1010 | 19 | 梁朝伟    |
+------+-----+---------------+
5 rows in set (0.00 sec)
mysql> select age '年龄',id as '学号' from stu order by 年龄 asc,学号 desc;
+--------+--------+
| 年龄  | 学号  |
+--------+--------+
|   18 |  1003 |
|   18 |  1001 |
|   19 |  1010 |
|   20 |  1005 |
|   20 |  1004 |
+--------+--------+

按函数排序

有学生表(id:编号,birth:出生日期,name:姓名),如下:

mysql> drop table if exists student;
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE TABLE student (
  ->  id int(11) NOT NULL COMMENT '学号',
  ->  birth date NOT NULL COMMENT '出生日期',
  ->  name varchar(16) DEFAULT NULL COMMENT '姓名',
  ->  PRIMARY KEY (id)
  -> );
Query OK, 0 rows affected (0.01 sec)
mysql> insert into student (id,birth,name) values (1001,'1990-10-10','路人甲Java'),(1005,'1960-03-01','刘德华'),(1003,'1960-08-16','张学友'),(1004,'1968-07-01','张国荣'),(1010,'1962-05-16','梁朝伟');
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql>
mysql> SELECT * FROM student;
+------+------------+---------------+
| id  | birth   | name     |
+------+------------+---------------+
| 1001 | 1990-10-10 | 路人甲Java  |
| 1003 | 1960-08-16 | 张学友    |
| 1004 | 1968-07-01 | 张国荣    |
| 1005 | 1960-03-01 | 刘德华    |
| 1010 | 1962-05-16 | 梁朝伟    |
+------+------------+---------------+
5 rows in set (0.00 sec)

需求:按照出生年份升序、编号升序,查询出编号、出生日期、出生年份、姓名,2种写法如下:

mysql> SELECT id 编号,birth 出生日期,year(birth) 出生年份,name 姓名 from student ORDER BY year(birth) asc,id asc;
+--------+--------------+--------------+---------------+
| 编号  | 出生日期   | 出生年份   | 姓名     |
+--------+--------------+--------------+---------------+
|  1003 | 1960-08-16  |     1960 | 张学友    |
|  1005 | 1960-03-01  |     1960 | 刘德华    |
|  1010 | 1962-05-16  |     1962 | 梁朝伟    |
|  1004 | 1968-07-01  |     1968 | 张国荣    |
|  1001 | 1990-10-10  |     1990 | 路人甲Java  |
+--------+--------------+--------------+---------------+
5 rows in set (0.00 sec)
mysql> SELECT id 编号,birth 出生日期,year(birth) 出生年份,name 姓名 from student ORDER BY 出生年份 asc,id asc;
+--------+--------------+--------------+---------------+
| 编号  | 出生日期   | 出生年份   | 姓名     |
+--------+--------------+--------------+---------------+
|  1003 | 1960-08-16  |     1960 | 张学友    |
|  1005 | 1960-03-01  |     1960 | 刘德华    |
|  1010 | 1962-05-16  |     1962 | 梁朝伟    |
|  1004 | 1968-07-01  |     1968 | 张国荣    |
|  1001 | 1990-10-10  |     1990 | 路人甲Java  |
+--------+--------------+--------------+---------------+
5 rows in set (0.00 sec)

说明:
year函数:属于日期函数,可以获取对应日期中的年份。
上面使用了2种方式排序,第一种是在order by中使用了函数,第二种是使用了别名排序。

where之后进行排序

有订单数据如下:

mysql> drop table if exists t_order;
Query OK, 0 rows affected, 1 warning (0.00 sec)
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.00 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)

需求:查询订单金额>=100的,按照订单金额降序排序,显示2列数据,列头:订单编号、订单金额,如下:

mysql> select a.id 订单编号,a.price 订单金额 from t_order a where a.price>=100 order by a.price desc;
+--------------+--------------+
| 订单编号   | 订单金额   |
+--------------+--------------+
|      3 |    500.00 |
|      4 |    300.00 |
|      6 |    200.50 |
|      2 |    100.68 |
+--------------+--------------+
4 rows in set (0.00 sec)

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的值不能用表达式
  • 分页排序时,排序不要有二义性,二义性情况下可能会导致分页结果乱序,可以在后面追加一个主键排序

到此这篇关于Mysql排序和分页(order by&limit)及存在的坑的文章就介绍到这了,更多相关Mysql排序和分页内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MYSQL 关于两个经纬度之间的距离由近及远排序

    复制代码 代码如下: select *,(2 * 6378.137* ASIN(SQRT(POW(SIN(PI()*(111.86141967773438-lat)/360),2)+COS(PI()*33.07078170776367/180)* COS(lat * PI()/180)*POW(SIN(PI()*(33.07078170776367-lng)/360),2)))) as juli from `area`  order by juli asc limit 0,20 差不多就是这样的

  • MySQL 千万级数据量如何快速分页

    前言 后端开发中为了防止一次性加载太多数据导致内存.磁盘IO都开销过大,经常需要分页展示,这个时候就需要用到MySQL的LIMIT关键字.但你以为LIMIT分页就万事大吉了么,Too young,too simple啊,LIMIT在数据量大的时候极可能造成的一个问题就是深度分页. 案例 这里我以显示电商订单详情为背景举个例子,新建表如下: CREATE TABLE `cps_user_order_detail` ( `id` bigint(20) unsigned NOT NULL AUTO_I

  • MySQL百万级数据分页查询优化方案

    当需要从数据库查询的表有上万条记录的时候,一次性查询所有结果会变得很慢,特别是随着数据量的增加特别明显,这时需要使用分页查询.对于数据库分页查询,也有很多种方法和优化的点.下面简单说一下我知道的一些方法. 准备工作 为了对下面列举的一些优化进行测试,下面针对已有的一张表进行说明. 表名:order_history 描述:某个业务的订单历史表 主要字段:unsigned int id,tinyint(4) int type 字段情况:该表一共37个字段,不包含text等大型数组,最大为varcha

  • MySQL中SQL分页查询的几种实现方法及优缺点

    [SQL]SQL分页查询总结 开发过程中经常遇到分页的需求,今天在此总结一下吧. 简单说来方法有两种,一种在源上控制,一种在端上控制.源上控制把分页逻辑放在SQL层:端上控制一次性获取所有数据,把分页逻辑放在UI上(如GridView).显然,端上控制开发难度低,适于小规模数据,但数据量增大时性能和IO消耗无法接受:源上控制在性能和开发难度上较为平衡,适应大多数业务场景:除此之外,还可以根据客观情况(性能要求,源与端的资源占用等)在源和端之间加一层,应用特殊算法和技术进行处理.以下主要讨论源上,

  • mysql如何根据汉字首字母排序

    复制代码 代码如下: select areaName from area order by convert(areaName USING gbk) COLLATE gbk_chinese_ci asc 说明:areaName为列名 area为表名 PS:这里再为大家推荐一款本站的相关在线工具供大家参考: 在线中英文根据首字母排序工具: http://tools.jb51.net/aideddesign/zh_paixu

  • 两种mysql对自增id重新从1排序的方法

    最近老是要为现在这个项目初始化数据,搞的很头疼,而且数据库的Id自增越来越大,要让自增重新从1开始:那么就用下面的方法吧: 方法一:如果曾经的数据都不需要的话,可以直接清空所有数据,并将自增字段恢复从1开始计数 truncate table 表名 方法二:dbcc checkident ('table_name', reseed, new_reseed_value) 当前值设置为 new_reseed_value.如果自创建表后没有将行插入该表,则在执行 DBCC CHECKIDENT 后插入的

  • mysql千万级数据分页查询性能优化

    mysql数据量大时使用limit分页,随着页码的增大,查询效率越低下. 实验 1.直接使用用limit start, count分页语句: select * from order limit start, count 当起始页较小时,查询没有性能问题,我们分别看下从10, 100, 1000, 10000开始分页的执行时间(每页取20条), 如下: select * from order limit 10, 20 0.016秒 select * from order limit 100, 20

  • Mysql如何查询某条记录在分页的第几页详析

    前言 在实践中我们会遇到这样的问题,知道某条记录的id,然后需要判断此条记录如果按照id进行排序分页,此条记录在第几页.今天这篇文章为大家提供一个思路. 下面话不多说了,来一起看看详细的实现方法吧 根据ID查询分页位置 根据ID来查询分页位置,比如按照ID的倒序排列,则可通过以下SQL查询出大于此ID记录数: select count(id) from user where id > 5; 示例中user为表名,5位待匹配的id.很显然,因为是倒序排序只需查找大于此id的记录数即可,如果是正序排

  • MySQL百万级数据量分页查询方法及其优化建议

    数据库SQL优化是老生常谈的问题,在面对百万级数据量的分页查询,又有什么好的优化建议呢?下面将列举了一些常用的方法,供大家参考学习! 方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N 适应场景: 适用于数据量较少的情况(元组百/千级) 原因/缺点: 全表扫描,速度会很慢 且 有的数据库结果集返回不稳定(如某次返回1,2,3,另外的一次返回2,1,3). Limit限制的是从结果集的M位置处取出N条输出,其余

  • Mysql排序和分页(order by&limit)及存在的坑

    排序查询(order by) 电商中:我们想查看今天所有成交的订单,按照交易额从高到低排序,此时我们可以使用数据库中的排序功能来完成. 排序语法: select 字段名 from 表名 order by 字段1 [asc|desc],字段2 [asc|desc]; 需要排序的字段跟在order by之后: asc|desc表示排序的规则,asc:升序,desc:降序,默认为asc: 支持多个字段进行排序,多字段排序之间用逗号隔开. 单字段排序 mysql> create table test2(

  • MySQL排序与分页讲解

    目录 一.order by 二.二级排序 三.分页limit 一.order by 使用 ORDER BY 对查询到的数据进行排序操作.升序:ASC (ascend)                    从低到高降序:DESC (descend)               从高到低 eg: 1.对stu表中的成绩(grade)从高到低排序 2.对stu表中的成绩(grade)从低到高排序 1.select * from stu order by drade desc; 2.select * 

  • MySql分页时使用limit+order by会出现数据重复问题解决

    目录 摘要 问题描述 分析问题 解决问题 摘要 能把复杂的知识讲的简单很重要 在学习的过程中我们看过很多资料.视频.文档等,因为现在资料视频都较多所以往往一个知识点会有多种多样的视频形式讲解.除了推广营销以外,确实有很多人的视频讲解非常优秀,例如李永乐老师的短视频课,可以在一个黑板上把那么复杂的知识,讲解的那么容易理解,那么透彻.而我们学习编程的人也是,不只是要学会把知识点讲明白,也要写明白. 问题描述 在 MySQL 中我们通常会采用 limit 来进行翻页查询,比如 limit(0,10)

  • MySQL 查询的排序、分页相关

    概述 数据库中的数据直接呈现出来一般不是我们想要的,所以我们上两节演示了如何对数据进行过滤的方法.除了对数据进行过滤, 我们可能还需要对数据进行排序,比如想从列表中了解消费最高的项,就可能需要对金额字段做降序排序,想看年龄从小到大的分布情况,就可能需要对user表的age字段进行升序排序. 也可能需要对数据进行限制,比如我们需要对付款的1~10,11~20,21~30 名的用户分别赠予不同的礼品,这时候对数据的限制就很有用了. 备注:下面脚本中[]包含的表示可选,| 分隔符表示可选其一. 数据排

  • MySQL利用索引优化ORDER BY排序语句的方法

    创建表&创建索引 create table tbl1 ( id int unique, sname varchar(50), index tbl1_index_sname(sname desc) ); 在已有的表创建索引语法 create [unique|fulltext|spatial] index 索引名 on 表名(字段名 [长度] [asc|desc]); MySQL也能利用索引来快速地执行ORDER BY和GROUP BY语句的排序和分组操作. 通过索引优化来实现MySQL的ORDER

  • 浅谈MySQL排序原理与案例分析

    前言 排序是数据库中的一个基本功能,MySQL也不例外.用户通过Order by语句即能达到将指定的结果集排序的目的,其实不仅仅是Order by语句,Group by语句,Distinct语句都会隐含使用排序.本文首先会简单介绍SQL如何利用索引避免排序代价,然后会介绍MySQL实现排序的内部原理,并介绍与排序相关的参数,最后会给出几个"奇怪"排序例子,来谈谈排序一致性问题,并说明产生现象的本质原因. 1.排序优化与索引使用 为了优化SQL语句的排序性能,最好的情况是避免排序,合理利

  • MySQL排序原理和案例详析

    前言 排序是数据库中的一个基本功能,MySQL也不例外.用户通过Order by语句即能达到将指定的结果集排序的目的,其实不仅仅是Order by语句,Group by语句,Distinct语句都会隐含使用排序.本文首先会简单介绍SQL如何利用索引避免排序代价,然后会介绍MySQL实现排序的内部原理,并介绍与排序相关的参数,最后会给出几个"奇怪"排序例子,来谈谈排序一致性问题,并说明产生现象的本质原因. 1.排序优化与索引使用 为了优化SQL语句的排序性能,最好的情况是避免排序,合理利

  • Mysql排序的特性详情

    目录 1.问题场景 2.原因分析 3.解决方案 4.拓展知识 4.1 limit查询优化 4.2 limit与order by结合使用 5.小结 1.问题场景 新上线一个交易记录导出功能,逻辑很简单:根据查询条件,导出对应的数据.由于数据量比较大,在查询数据库时采用了分页查询,每次查询1000条数据. 自测正常,测试环境正常,上线之后运营反馈导出的数据有重复记录. 原本是以为业务逻辑问题,重新Review了一遍代码,依旧未找到问题原因.最后只好把SQL语句拿出来单独执行,导出数据,对比发现竟然是

  • 浅谈Mysql大数据分页查询解决方案

    目录 1.简介 2.分页插件使用 3.sql测试与分析 3.1 limit现象分析 3.2 解决之道 4 测试时走过的坑 4.1 百万数据内容都一样 4.2 写sql时,把"77"写成了77: 4.3 一个有趣的现象 总结 1.简介 之前,面阿里的时候,有个面试官问我有没有使用过分页查询,我说有,他说分页查询是有问题的,怎么解决:后来这个问题我没有回答出来:本着学习的态度,今天来解决一下这个问题: 2.分页插件使用 1.pom文件 <dependency> <grou

  • 浅析Mysql和Oracle分页的区别

    目录 MySQL使用limit进行分页 Oracle使用rownum进行分页 Mysql与Oracle级联查询 Mysql省市区级联查询 Mysql与Oracle插入数据存在修改不存在新增 MySQL使用limit进行分页 select * from stu limit m,n; // m=(pageIndex-1)*pageSize,n=pageSize -- 返回总条,查询表添加字段sql_calc_found_rows select sql_calc_found_rows a.* from

随机推荐