PostgreSQL的分页与限制

1,058 阅读2分钟

分页需求

正常的数据查询需求一般都需要进行分页操作,对于后端来说,不希望一次读取大量的数据,造成数据库的负担;对于前端来说,不希望一次展示过多数据,影响用户的交互体验。

PostgreSQL与MySQL分页的区别

  • 如果从第一条开始取记录 , pg与mysql都支持 select * from tb limit A;
  • 当从至少第二条数据取记录时 , pg 仅支持 limit A offset B , 而 mysql 除了支持 pg 的分页之外 , 还支持 limit B,A。

PostgreSQL 的分页

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子句与LIMIT子句作用相同,但 FETCH 是标准SQL语法,而LIMIT是PostgreSQL扩展语法。
  • 不指定 ORDER BY,则结果集不进行排序。
  • FIRST 和 NEXT 任选一个,两者含义相同。
  • ROW 和ROWS 任选一个,两个含义相同。
  • OFFSET 偏移量必须为 0 或者正整数。默认值为 0,NULL等同于 0。
  • FETCH 限制数量必须为 0 或者正整数。默认值为 1,NULL等同于不限制数量。
  • LIMIT 限制数量必须为 0 或者正整数。没有默认值,ALL 或者 NULL 等同于不限制数量。
  • 随着 OFFSET 偏移量的增加,查询耗时线性增长,相当于先取出 OFFSET + LIMIT 的行之后,再把 OFFSET 的行去掉。

PostgreSQL 的 WITH TIES

给定一张成绩表scores

idnamescore
1alice90
2alex80
3xiaobai80
4xiaoming80
5daviad70

获取成绩最高的top 2

SELECT * FROM scores
ORDER BY score DESC
LIMIT 2;

SELECT * FROM scores
ORDER BY score DESC
FETCH FIRST 2 ROWS ONLY;
idnamescore
1alice90
2alex80

同等条件下获取所有重复值,使用 WITH TIES 子句。

SELECT * FROM scores
ORDER BY score DESC
FETCH FIRST 2 ROWS WITH TIES;
idnamescore
1alice90
2alex80
3xiaobai80
4xiaoming80

...