玩转Mysql系列 - 第8篇:详解排序和分页(order by & limit),及存在的坑

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;

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

总结

我个人认为,如果你想靠着背面试题来获得心仪的offer,用癞蛤蟆想吃天鹅肉形容完全不过分。想必大家能感受到面试越来越难,想找到心仪的工作也是越来越难,高薪工作羡慕不来,却又对自己目前的薪资不太满意,工作几年甚至连一个应届生的薪资都比不上,终究是错付了,错付了自己没有去提升技术。

这些面试题分享给大家的目的,其实是希望大家通过大厂面试题分析自己的技术栈,给自己梳理一个更加明确的学习方向,当你准备好去面试大厂,你心里有底,大概知道面试官会问多广,多深,避免面试的时候一问三不知。

大家可以把Java基础,JVM,并发编程,MySQL,Redis,Spring,Spring cloud等等做一个知识总结以及延伸,再去进行操作,不然光记是学不会的,这里我也提供一些脑图分享给大家:

希望你看完这篇文章后,不要犹豫,抓紧学习,复习知识,准备在明年的金三银四拿到心仪的offer,加油,打工人!
程,基本涵盖了95%以上Java开发知识点,真正体系化!**

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-DaFe6d6g-1711870678874)]

总结

我个人认为,如果你想靠着背面试题来获得心仪的offer,用癞蛤蟆想吃天鹅肉形容完全不过分。想必大家能感受到面试越来越难,想找到心仪的工作也是越来越难,高薪工作羡慕不来,却又对自己目前的薪资不太满意,工作几年甚至连一个应届生的薪资都比不上,终究是错付了,错付了自己没有去提升技术。

这些面试题分享给大家的目的,其实是希望大家通过大厂面试题分析自己的技术栈,给自己梳理一个更加明确的学习方向,当你准备好去面试大厂,你心里有底,大概知道面试官会问多广,多深,避免面试的时候一问三不知。

大家可以把Java基础,JVM,并发编程,MySQL,Redis,Spring,Spring cloud等等做一个知识总结以及延伸,再去进行操作,不然光记是学不会的,这里我也提供一些脑图分享给大家:

[外链图片转存中…(img-OVzJLeHV-1711870678874)]

[外链图片转存中…(img-Ee7gTO8F-1711870678875)]

[外链图片转存中…(img-aD2dSvl4-1711870678875)]

希望你看完这篇文章后,不要犹豫,抓紧学习,复习知识,准备在明年的金三银四拿到心仪的offer,加油,打工人!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值