PostgreSQL - 从LIMIT OFFSET重复行

时间:2012-11-27 09:16:27

标签: sql postgresql sql-order-by limit offset

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

当我运行此查询时:

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 |

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

3 个答案:

答案 0 :(得分:36)

  

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

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

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

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

如果两行的状态列具有相同的值,则它们将按ID排序。

答案 1 :(得分:13)

有关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约束订单。

答案 2 :(得分:0)

select * from(
    Select "students".* 
    from "students" 
    order by "students"."status" asc 
    limit 6
) as temp limit 3 offset 0;
select * from(
    Select "students".* 
    from "students" 
    order by "students"."status" asc 
    limit 6
) as temp limit 3 offset 3;

其中 6 是正在检查的记录总数。

相关问题