我在一个分页记录注意到一些重复的行。
当我运行此查询:
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 |
为什么“富”同时出现在查询?
由于所有返回的行具有了相同的值status
列。 在这种情况下,数据库可以自由地在它想要的任何顺序返回行。
如果你想要一个可再现订购你需要声明第二列添加到您的订单,使其保持一致。 例如ID列:
SELECT students.*
FROM students
ORDER BY students.status asc,
students.id asc
如果两行对状态栏的值相同,他们将通过ID进行排序。
从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来约束顺序固有的后果。