ITPub博客

首页 > 数据库 > 数据库开发技术 > 《PostgreSQL 开发指南》第 12 篇 限定数量

《PostgreSQL 开发指南》第 12 篇 限定数量

原创 数据库开发技术 作者:BUAA_dxy 时间:2022-02-28 20:41:02 0 删除 编辑

查询语句的结果可能包含成百上千行数据,但是前端显示时也许只需要其中的一小部分,例如 TOP-N 排行榜;或者为了便于查看,每次只显示一定数量的结果,例如分页功能。为了处理这类应用,SQL 提供了标准的FETCH和OFFSET子句。另外,PostgreSQL 还实现了扩展的LIMIT语法。

Top-N 查询

这类查询通常是为了找出排名中的前多少个记录,例如以下语句查询薪水最高的前 10 名员工,使用FETCH语法:

SELECT first_name, last_name, salary
FROM employees
ORDER BY salary DESC
FETCH FIRST 10 ROWS ONLY;
first_name|last_name|salary |
----------|---------|--------|
Steven |King |24000.00|
Lex |De Haan |17000.00|
Neena |Kochhar |17000.00|
John |Russell |14000.00|
Karen |Partners |13500.00|
Michael |Hartstein|13000.00|
Shelley |Higgins |12008.00|
Nancy |Greenberg|12008.00|
Alberto |Errazuriz|12000.00|
Lisa |Ozer |11500.00|

其中,FIRST也可以写成NEXT,ROWS也可以写成ROW。结果返回了排序之后的前 10 条记录。

使用LIMIT语法也可以实现相同的功能:

SELECT first_name, last_name, salary
FROM employees
ORDER BY salary DESC
LIMIT 10;

分页查询

许多应用都支持分页显示的功能,即每页显示一定数量的记录(例如 10 行、20行等),同时提供类似上一页和下一页的导航。使用 SQL 实现这种功能需要引入另一个子句:OFFSET。

假设我们的应用提供了分页显示,每页显示 10 条记录。现在用户点击了下一页,需要显示第 11 到第 20 条记录。使用标准 SQL 语法实现如下:

SELECT first_name, last_name, salary
FROM employees
ORDER BY salary DESC
OFFSET 10 ROWS
FETCH FIRST 10 ROWS ONLY;
first_name|last_name|salary |
----------|---------|--------|
Gerald |Cambrault|11000.00|
Den |Raphaely |11000.00|
Ellen |Abel |11000.00|
Clara |Vishney |10500.00|
Eleni |Zlotkey |10500.00|
Harrison |Bloom |10000.00|
Peter |Tucker |10000.00|
Janette |King |10000.00|
Hermann |Baer |10000.00|
Tayler |Fox | 9600.00|

OFFSET表示先忽略掉多少行数据,然后再返回后面的结果。ROWS也可以写成ROW。对于应用程序而言,只需要传入不同的OFFSET偏移量和FETCH数量,就可以在结果中任意导航。

使用LIMIT加上OFFSET同样可以实现分页效果:

SELECT first_name, last_name, salary
FROM employees
ORDER BY salary DESC
LIMIT 10 OFFSET 10;

注意事项

我们先看一下完整的FETCH和LIMIT语法:

SELECT column1, column2, ...
FROM table
[WHERE conditions]
[ORDER BY column1 ASC, column2 DESC, ...]
[OFFSET m {ROW | ROWS}]
[FETCH { FIRST | NEXT } [ num_rows] { ROW | ROWS } ONLY];

SELECT column1, column2, ...
FROM table
[WHERE conditions]
[ORDER BY column1 ASC, column2 DESC, ...]
[LIMIT { num_rows| ALL } ]
[OFFSET m {ROW | ROWS}];

在使用以上功能时需要注意以下问题:

  • FETCH是标准 SQL 语法,LIMIT是 PostgreSQL 扩展语法。

  • 如果没有指定ORDER BY,限定数量之前并没有进行排序,是一个随意的结果。

  • OFFSET偏移量必须为 0 或者正整数。默认为 0,NULL 等价于 0。

  • FETCH限定的数量必须为 0 或者正整数。默认为 1,NULL 等价于不限定数量。

  • LIMIT限定的数量必须为 0 或者正整数。没有默认值,ALL 或者 NULL 等价于不限定数量。

  • 随着OFFSET的增加,查询的性能会越来越差。因为服务器需要计算更多的偏移量,即使这些数据不需要被返回前端。

原文作者:SQL编程思想;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论
《SQL编程思想》作者,专注于数据库领域知识的分享。

注册时间:2021-08-26

  • 博文量
    443
  • 访问量
    546975