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

时间:2012-02-22 19:07:16

标签: sql ruby-on-rails postgresql activerecord sql-order-by

所以基本上我有这个范围(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 个答案:

答案 0 :(得分:6)

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

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

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

或类似的东西,具体取决于您需要的具体顺序。