PostgreSQL - 从LIMIT OFFSET重复行

kee*_*ooi 27 sql postgresql sql-order-by limit offset

我注意到分页记录集中有一些重复的行.

当我运行此查询时:

SELECT "students".* 
FROM "students" 
ORDER BY "students"."status" asc 
LIMIT 3 OFFSET 0
Run Code Online (Sandbox Code Playgroud)

我明白了:

    | id | name  | status |
    | 1  | foo   | active |
    | 12 | alice | active |
    | 4  | bob   | active |
Run Code Online (Sandbox Code Playgroud)

下一个查询:

SELECT "students".* 
FROM "students" 
ORDER BY "students"."status" asc 
LIMIT 3 OFFSET 3
Run Code Online (Sandbox Code Playgroud)

我明白了:

    | id | name  | status |
    | 1  | foo   | active |
    | 6  | cindy | active |
    | 2  | dylan | active |
Run Code Online (Sandbox Code Playgroud)

为什么"foo"出现在两个查询中?

a_h*_*ame 40

为什么"foo"出现在两个查询中?

因为返回的所有行都具有相同的status列值.在这种情况下,数据库可以按任何顺序自由返回行.

如果您需要可重复排序,则需要在订单中添加第二列以使其保持一致.例如ID列:

SELECT students.* 
FROM students 
ORDER BY students.status asc, 
         students.id asc
Run Code Online (Sandbox Code Playgroud)

如果两行具有相同的status列值,则它们将按id排序.

  • 谢谢你的回答!这只是 PostgreSQL 吗?我无法在 MySQL 中重现这种行为。 (2认同)

Ahm*_*OUR 15

有关PostgreSQL文档的更多详细信息(http://www.postgresql.org/docs/8.3/static/queries-limit.html):

使用LIMIT时,使用ORDER BY子句将结果行限制为唯一顺序非常重要.否则,您将获得查询行的不可预测的子集.您可能会要求第十到第二十行,但第十到第二十行是什么排序?除非您指定了ORDER BY,否则排序是未知的.

查询优化器在生成查询计划时会考虑LIMIT,因此您很可能会获得不同的计划(产生不同的行顺序),具体取决于您为LIMIT和OFFSET提供的内容.因此,使用不同的LIMIT/OFFSET值来选择查询结果的不同子集将产生不一致的结果,除非您使用ORDER BY强制执行可预测的结果排序.这不是一个bug; 这是SQL不承诺以任何特定顺序传递查询结果这一事实的固有后果,除非使用ORDER BY来约束订单.