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排序.
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来约束订单.