CodeGym /课程 /SQL SELF /使用OFFSET跳过行和实现分页

使用OFFSET跳过行和实现分页

SQL SELF
第 3 级, 课程 1
可用

先问你个问题:你在网店网站上看到一页太多商品怎么办?没错,你点下一页。那后台发生了啥?其实就是SQL的魔法——用OFFSET命令跳过一些行。今天你会知道啥是OFFSET,它有啥用,怎么用,以及为啥它是分页的基础。

OFFSET是SQL里的一个关键字,可以让你在查询结果里跳过指定数量的行。就像翻书一样:你可以“跳过”前10行,从第11行开始看。

语法

SELECT 列1, 列2
FROM 表
OFFSET 跳过的行数;
  • OFFSET —— 跳过行的关键字。
  • 跳过的行数 —— 你想跳过多少行。

简单的OFFSET用法例子

假设我们有个表叫students,数据如下:

id name age
1 爱丽丝 22
2 鲍勃 24
3 克拉拉 23
4 丹 21
5 伊娃 25

我们想从第三个学生开始显示。可以这样写:

SELECT *
FROM students
OFFSET 2;

结果:

id name age
3 克拉拉 23
4 丹 21
5 伊娃 25

SQL“跳过”了前两行(爱丽丝和鲍勃),结果从第三行开始。就像用书签一样:“这页看过了,翻下一页”。

OFFSET和LIMIT一起用

OFFSET通常和LIMIT一起用。这样你可以跳过一些行,同时只取你想要的数量。这对分页(page=页面)特别有用——每次只显示几行。

比如我们想每次显示2条,从第三行开始。SQL写法:

SELECT *
FROM students
LIMIT 2 
OFFSET 2;

结果:

id name age
3 克拉拉 23
4 丹 21

逻辑如下:

  1. OFFSET 2跳过前两行:爱丽丝和鲍勃。
  2. LIMIT 2只取剩下的两行。

实现分页

现在到了最有意思的部分——分页。假设你做了个学生列表的web应用。你想每页显示2条,怎么搞?

核心思路:

  • 第一页不跳过行:OFFSET 0。
  • 第二页跳过2行:OFFSET 2。
  • 第三页跳过4行:OFFSET 4。
  • 以此类推……

例子:显示第二页

第一页显示1和2(爱丽丝和鲍勃)。第二页显示3和4(克拉拉和丹)。

SELECT *
FROM students
ORDER BY id
LIMIT 2 
OFFSET 2;

结果:

id name age
3 克拉拉 23
4 丹 21

例子:显示第三页

第三页显示5和6(如果有的话)。

SELECT *
FROM students
ORDER BY id
LIMIT 2 
OFFSET 4;

结果:

id name age
5 伊娃 25

计算OFFSET的公式

做分页系统时,可以用下面这个公式自动算:

OFFSET = (页码 - 1) * 每页条数

比如:

  • 第一页:(1 - 1) * 2 = 0。
  • 第二页:(2 - 1) * 2 = 2。
  • 第三页:(3 - 1) * 2 = 4。

性能注意事项

当你操作大表时,OFFSET可能会变慢,尤其是后面的页面。因为PostgreSQL还是会扫描被跳过的行。比如OFFSET 10000,数据库得先查完前10000行才能给你结果。这种情况可以考虑别的方法,比如用唯一id当分页标记。

替代方案:用游标分页

想优化的话,可以用“游标”方式。不是用OFFSET跳行,而是记住上一页最后一行的id,下次用它来查:

SELECT *
FROM students
WHERE id > 上一页最后id
ORDER BY id
LIMIT 2;

这种方式在大表里会快很多。

分页的实际应用

分页在大多数web应用里都用得到:网店、博客、后台管理面板。比如:

  • 网店商品列表分页;
  • CRM系统用户列表分页;
  • 新闻流分页显示。

分析大数据时,分页也很有用,可以分批处理。

用OFFSET常见错误

刚学OFFSET时经常会踩坑,下面是常见的几个:

没加排序。 如果你没写ORDER BY,OFFSET结果的顺序可能乱七八糟。

错误写法:

SELECT * FROM students
OFFSET 5;

正确写法:

SELECT * FROM students
ORDER BY id
OFFSET 5;

OFFSET值写错。 如果写太大,结果就是空的。

性能问题。 前面说过,OFFSET太大时会很慢。

没加过滤条件。 如果你用OFFSET和LIMIT但没加WHERE,可能会查到一堆没用的数据,性能也会差。

操作符顺序。 SQL里操作符顺序是固定的:先LIMIT,再OFFSET。可以省略,但不能换顺序。

2
任务
SQL SELF, 第 3 级, 课程 1
已锁定
使用 `OFFSET` 跳过行
使用 `OFFSET` 跳过行
2
任务
SQL SELF, 第 3 级, 课程 1
已锁定
分页显示数据
分页显示数据
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION