postgresql,奇怪的 OFFSET/LIMIT 行为(记录顺序)

Posted

技术标签:

【中文标题】postgresql,奇怪的 OFFSET/LIMIT 行为(记录顺序)【英文标题】:postgresql, odd OFFSET/LIMIT behavior ( records order ) 【发布时间】:2012-02-22 19:07:16 【问题描述】:

所以基本上我有这个范围(sql):

scope.to_sql
=> "SELECT  \"offers\".* FROM \"offers\" INNER JOIN \"cities_offers\" ON \"offers\".\"id\" = \"cities_offers\".\"offer_id\" WHERE \"cities_offers\".\"city_id\" = 2 AND \"offers\".\"category_id\" IN (2) AND (offers.category_id is NOT NULL) ORDER BY offers.discount desc LIMIT 25 OFFSET 0"

不知何故,上述查询的记录顺序与没有 LIMIT 和 OFFSET 的相同查询不同:

   scope[6]
=> #<Offer id: 8629 ...

scope.except(:offset, :limit)[6]
=> #<Offer id: 8729 ...

8629 和 8729 记录具有相同的 discount 值(我排序的属性)。

您能否建议在这种情况下是否可以保持相同的记录排序?

【问题讨论】:

【参考方案1】:

关系数据库是基于集合的,因此本质上是无序的;结果集中记录的顺序由 ORDER BY 子句指定。如果 ORDER BY 子句中的表达式的两行具有相同的值,则运行相同的查询两次可能会返回不同位置的这些行;通过添加 LIMIT 和 OFFSET 来更改查询只会使事情变得更糟,因为更有可能产生不同的顺序。

如果您希望数据库按特定顺序为您提供行,您必须在 ORDER BY 子句中完全指定顺序。您必须在您的范围内向order 调用添加更多内容:

...order('offers.discount desc, offers.created_at asc')

或类似的东西取决于您需要的特定订单。

【讨论】:

以上是关于postgresql,奇怪的 OFFSET/LIMIT 行为(记录顺序)的主要内容,如果未能解决你的问题,请参考以下文章

postgresql,奇怪的 OFFSET/LIMIT 行为(记录顺序)

PostgreSQL 与 array_to_json 的奇怪行为

我遇到了一个奇怪的问题,使用 NOT IN 对 PostgreSQL 数据库运行查询,但不明白为啥它不起作用

将一个奇怪的 Mysql 查询更改为使用 group_concat 的 Postgresql

转:PostgreSQL的clog—从事务回滚速度谈起

Oracle表空间和PostgreSQL表空间的区别?