您现在的位置是:网站首页> 编程资料编程资料

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

2023-05-27 481人已围观

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

排序查询(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 s
                
                

-六神源码网