的PostgreSQL - 重复从LIMIT行OFFSET(PostgreSQL - repeat

2019-07-04 04:15发布

我在一个分页记录注意到一些重复的行。

当我运行此查询:

SELECT "students".* 
FROM "students" 
ORDER BY "students"."status" asc 
LIMIT 3 OFFSET 0

我得到:

    | id | name  | status |
    | 1  | foo   | active |
    | 12 | alice | active |
    | 4  | bob   | active |

接下来的查询:

SELECT "students".* 
FROM "students" 
ORDER BY "students"."status" asc 
LIMIT 3 OFFSET 3

我得到:

    | id | name  | status |
    | 1  | foo   | active |
    | 6  | cindy | active |
    | 2  | dylan | active |

为什么“富”同时出现在查询?

Answer 1:

由于所有返回的行具有了相同的值status列。 在这种情况下,数据库可以自由地在它想要的任何顺序返回行。

如果你想要一个可再现订购你需要声明第二列添加到您的订单,使其保持一致。 例如ID列:

SELECT students.* 
FROM students 
ORDER BY students.status asc, 
         students.id asc

如果两行对状态栏的值相同,他们将通过ID进行排序。



Answer 2:

从PostgreSQL文档(更多详情http://www.postgresql.org/docs/8.3/static/queries-limit.html ):

如果使用LIMIT, 使用的ORDER BY结果行约束成一个唯一的顺序条款是很重要的。 否则,你会得到查询的行不可预测的子集。 你可能会问到二十行以什么顺序第十,但十到二十? 顺序是不知道的,除非你指定的ORDER BY。

查询优化器会考虑LIMIT生成查询规划的时候,所以你很可能得到这取决于你给LIMIT和OFFSET不同的规划(产生不同的行顺序)。 因此,使用不同的LIMIT / OFFSET值选择一个查询结果的子集将生成不一致的结果,除非你强制执行可预料的顺序与ORDER BY。 这是不是一个错误; 这是一个事实,即SQL没有许诺把查询的结果按照任何特定的顺序,除非用了ORDER BY来约束顺序固有的后果。



文章来源: PostgreSQL - repeating rows from LIMIT OFFSET