泰安网站建设方案书,找做金融的网站有哪些,较好的网站设计师培训学校,android移动应用开发这是Mysql系列第7篇。
环境#xff1a;mysql5.7.25#xff0c;cmd命令中进行演示。
代码中被[]包含的表示可选#xff0c;|符号分开的表示可选其一。
本章内容 详解排序查询 详解limit limit存在的坑 分页查询中的坑
排序查询#xff08;order by#xff09;
电商…这是Mysql系列第7篇。
环境mysql5.7.25cmd命令中进行演示。
代码中被[]包含的表示可选|符号分开的表示可选其一。
本章内容 详解排序查询 详解limit 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: 0mysql 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: 0mysql 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: 0mysql
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: 0mysql 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.price100 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: 0mysql 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-n1条记录如下
select 列 from 表 limit n-1,m-n1;如我们想获取订单金额最高的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 2pageSize 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,41;
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,41 at line 1
mysql select * from t_order where limit 10;
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 10 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: 0mysql 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个参数offsetcountoffset表示跳过多少行count表示跳过offset行之后取count行 limit中offset可以省略默认值为0 limit中offset 和 count都必须大于等于0 limit中offset和count的值不能用表达式 分页排序时排序不要有二义性二义性情况下可能会导致分页结果乱序可以在后面追加一个主键排序