网站首页 > 知识剖析 正文
恭喜你,已经完全掌握了数据的增、删、改、查(CRUD)四大金刚!
现在,我们的查询能力还差最后一点“仪式感”。目前我们 SELECT 出来的数据,顺序都是数据库说了算,有点杂乱无章。如果我们想让结果按照我们指定的规则排列,比如“按年龄从小到大”或者“按认识时间从长到短”,该怎么办呢?
这一章,我们就来学习两个让查询结果变得井然有序的强大武器:
- ORDER BY: 对结果进行排序。
- LIMIT: 限制返回结果的数量,实现“分页”等功能。
准备工作:更多的数据
为了让排序效果更明显,我们需要一个稍微大一点的数据集。老规矩,TRUNCATE 清空后重新插入:
TRUNCATE TABLE friends;
INSERT INTO friends (id, name, birthday, years_known)
VALUES
(1, '老王', '1990-05-20', 5),
(2, '李雷', '1992-08-15', 3),
(3, '张三', '1988-01-30', 11),
(4, '韩梅梅', '1992-08-15', 3),
(5, '赵四', '1978-11-11', 16),
(6, '刘能', '1979-03-12', 16);
注意,我们让李雷和韩梅梅的生日与认识年数都相同,赵四和刘能的认识年数也相同,这是为了后面演示多列排序。
9.1ORDER BY:给你的结果排排坐
ORDER BY 子句允许你根据一列或多列的值,对 SELECT 查询返回的结果集进行排序。
基本语法:
ORDER BY 子句通常放在 SELECT 语句的最后面。
SELECT column_list
FROM table_name
WHERE condition
ORDER BY column_to_sort_by [ASC | DESC];
- ASC (Ascending): 升序排列。从小到大,从早到晚。这是默认的排序方式。
- DESC (Descending): 降序排列。从大到小,从晚到早。
示例 1:按认识年数升序排列
找出所有朋友,并按照我们认识他们的年数,从短到长排列。
SELECT name, years_known FROM friends
ORDER BY years_known ASC;
因为 ASC 是默认的,所以也可以省略不写:ORDER BY years_known;
结果:
name | years_known
----------+-------------
李雷 | 3
韩梅梅 | 3
老王 | 5
张三 | 11
赵四 | 16
刘能 | 16
(6 rows)
示例 2:按生日降序排列(谁最年轻)
找出所有朋友,并按照他们的生日,从最近到最远排列(也就是从大到小,最年轻的在最前面)。
SELECT name, birthday FROM friends
ORDER BY birthday DESC;
结果:
name | birthday
----------+------------
李雷 | 1992-08-15
韩梅梅 | 1992-08-15
老王 | 1990-05-20
刘能 | 1979-03-12
赵四 | 1978-11-11
张三 | 1988-01-30
(6 rows)
9.2 多列排序
观察上面两个例子,你会发现一个问题:
- 当按 years_known 排序时,李雷和韩梅梅都是 3 年,他们的前后顺序是不确定的。
- 当按 birthday 排序时,李雷和韩梅梅生日相同,顺序也是不确定的。
如果我们希望在主排序键值相同的情况下,再按第二个、第三个键进行排序,就需要多列排序。
示例 3:按认识年数降序,如果年数相同,再按名字升序
我们想看看认识最久的朋友。如果认识时间一样长(比如赵四和刘能),那就按名字的字母顺序排。
SELECT name, years_known FROM friends
ORDER BY years_known DESC, name ASC;
- 数据库会首先按照 years_known DESC 来排序。
- 当遇到 years_known 相等的行时,它会在这几行内部,再按照 name ASC 进行二次排序。
结果(注意赵四和刘能的顺序):
name | years_known
----------+-------------
刘能 | 16 -- 刘(L)在赵(Z)前面
赵四 | 16
张三 | 11
老王 | 5
李雷 | 3 -- 李(L)在韩(H)后面
韩梅梅 | 3
(6 rows)
Oops, 拼音排序和数据库默认的字符集排序可能不一致,但重点是它们之间有了一个确定的顺序!
9.3LIMIT和OFFSET:分页查询的核心
当我们的表里有成千上万条数据时,一次性把它们全都查出来显示给用户,显然是不现实的。这不仅慢,而且用户也看不过来。
这时,我们就需要“分页”——每次只显示一小部分数据。LIMIT 和 OFFSET 就是实现这个功能的神器。
- LIMIT [count]: 限制最多返回 count 条记录。
- OFFSET [count]: 跳过开头的 count 条记录。
LIMIT 和 OFFSET 必须和 ORDER BY 一起使用! 否则,你每次跳过和获取的记录都是不确定的,分页就乱套了。
示例 4:找出我们认识最久的前 3 位朋友
SELECT name, years_known FROM friends
ORDER BY years_known DESC
LIMIT 3;
结果:
name | years_known
----------+-------------
赵四 | 16
刘能 | 16
张三 | 11
(3 rows)
示例 5:实现分页查询
假设我们每页显示 2 条记录,我们想看第 2 页的数据。
- 第 1 页: LIMIT 2 OFFSET 0 (跳过0条,取2条)
- 第 2 页: LIMIT 2 OFFSET 2 (跳过2条,取2条)
- 第 3 页: LIMIT 2 OFFSET 4 (跳过4条,取2条)
让我们来获取第 2 页的数据:
SELECT id, name, years_known FROM friends
ORDER BY id ASC -- 使用一个绝对唯一的键来排序,保证分页稳定
LIMIT 2 OFFSET 2;
结果(ID为 1, 2 的被跳过):
id | name | years_known
----+------+-------------
3 | 张三 | 11
4 | 韩梅梅 | 3
(2 rows)
本章小结
太棒了!你已经学会了如何驾驭查询结果的呈现方式。
- 我们学会了用 ORDER BY 对结果进行升序 (ASC) 和 降序 (DESC) 排列。
- 掌握了多列排序,让排序规则更精细。
- 学会了用 LIMIT 和 OFFSET 来实现获取 Top N 和 分页 这两个极其有用的功能。
至此,SQL 的基础查询部分(第二部分)已经全部完成!你现在拥有的技能,已经足以应对日常 80% 的数据查询和操作任务了。
从下一章开始,我们将进入一个更高级的领域:聚合与分组。我们将学习如何对数据进行统计分析,比如“计算我们朋友的平均年龄”、“统计每年认识了几个朋友”等等。准备好从数据中挖掘更深层次的洞见了吗?我们下一章见!
猜你喜欢
- 2025-09-03 SQL轻松入门(5):窗口函数_sql的窗口函数面试题
- 2025-09-03 一条order by rand的SQL为什么能打爆服务器磁盘?
- 2025-09-03 日进一步,sql语句之排序语句order by
- 2025-09-03 一文讲懂 SQL 排序子句 ORDER BY_排序语句sql
- 09-03告别 MongoDB?PostgreSQL JSONB 让关系型数据库玩转非结构化数据!
- 09-03Struts框架s2-29远程代码执行漏洞猜想
- 09-03解决提示词痛点:用AI智能体自动检测矛盾、优化格式的完整方案
- 09-03我恨了爷爷24年, 他去世后打开遗物, 一只虎头鞋让我跪在坟前不起
- 09-03酷瓜云课堂(内网版)v1.2.2 发布,局域网在线课程系统
- 09-03SQL轻松入门(5):窗口函数_sql的窗口函数面试题
- 09-03一条order by rand的SQL为什么能打爆服务器磁盘?
- 09-03第 9 章:排序与限制 (ORDER BY, LIMIT) - PostgreSQL入门
- 最近发表
-
- 告别 MongoDB?PostgreSQL JSONB 让关系型数据库玩转非结构化数据!
- Struts框架s2-29远程代码执行漏洞猜想
- 解决提示词痛点:用AI智能体自动检测矛盾、优化格式的完整方案
- 我恨了爷爷24年, 他去世后打开遗物, 一只虎头鞋让我跪在坟前不起
- 酷瓜云课堂(内网版)v1.2.2 发布,局域网在线课程系统
- SQL轻松入门(5):窗口函数_sql的窗口函数面试题
- 一条order by rand的SQL为什么能打爆服务器磁盘?
- 第 9 章:排序与限制 (ORDER BY, LIMIT) - PostgreSQL入门
- 日进一步,sql语句之排序语句order by
- 一文讲懂 SQL 排序子句 ORDER BY_排序语句sql
- 标签列表
-
- xml (46)
- css animation (57)
- array_slice (60)
- htmlspecialchars (54)
- position: absolute (54)
- datediff函数 (47)
- array_pop (49)
- jsmap (52)
- toggleclass (43)
- console.time (63)
- .sql (41)
- ahref (40)
- js json.parse (59)
- html复选框 (60)
- css 透明 (44)
- css 颜色 (47)
- php replace (41)
- css nth-child (48)
- min-height (40)
- xml schema (44)
- css 最后一个元素 (46)
- location.origin (44)
- table border (49)
- html tr (40)
- video controls (49)