【问题标题】:Does postgres offset/limit not work the same way as mysql?postgres 偏移量/限制与 mysql 的工作方式不同吗?
【发布时间】:2012-07-26 20:06:46
【问题描述】:

我有一个带有评分列(整数)的 post 模型的 rails 应用程序(postgres + postGIS)。如果我进入控制台并执行以下操作:

Post.order("rating DESC").map(&:id)
=> [9, 15, 19, 6, 17, 5, 4, 16, 1, 3, 13, 20, 14, 10, 8, 12, 7, 2, 18, 11]

但是,如果我尝试使用限制和偏移量一次循环通过那些,我会得到奇怪的结果。

Post.order("rating DESC").limit(1).offset(0)
=> [#<Post id: 5, body: "Hi", rating: 4, location: #<RGeo::Geographic::SphericalPointImpl:0x81bb34c0 "POINT (-118.495 34.017)">, user_id: 8, created_at: "2012-07-25 22:43:41", updated_at: "2012-07-25 22:43:41">]

为什么那个帖子是#5?应该是#9。无论如何,当我应用偏移量时,它会变得更加古怪。

>Post.order("rating DESC").limit(1).offset(1)
=> [#<Post id: 5, body: "Hi", rating: 4, location: #<RGeo::Geographic::SphericalPointImpl:0x81bb34c0 "POINT (-118.495 34.017)">, user_id: 8, created_at: "2012-07-25 22:43:41", updated_at: "2012-07-25 22:43:41">]

>Post.order("rating DESC").limit(1).offset(2)
=> [#<Post id: 5, body: "Hi", rating: 4, location: #<RGeo::Geographic::SphericalPointImpl:0x81bb34c0 "POINT (-118.495 34.017)">, user_id: 8, created_at: "2012-07-25 22:43:41", updated_at: "2012-07-25 22:43:41">]

>Post.order("rating DESC").limit(1).offset(3)
=> [#<Post id: 5, body: "Hi", rating: 4, location: #<RGeo::Geographic::SphericalPointImpl:0x81bb34c0 "POINT (-118.495 34.017)">, user_id: 8, created_at: "2012-07-25 22:43:41", updated_at: "2012-07-25 22:43:41">]

>Post.order("rating DESC").limit(1).offset(4)
=> [#<Post id: 15, body: "I luv coffee", rating: 4, flagged: 0, location: #<RGeo::Geographic::SphericalPointImpl:0x82260df4 "POINT (-118.495 34.017)">, user_id: 1, created_at: "2012-07-25 22:43:41", updated_at: "2012-07-25 22:43:41">]

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 postgresql postgis


    【解决方案1】:

    您是否注意到rating 是您显示的唯一结果中的 4?您正在对 rating 进行排序,没有辅助排序键,因此无法保证将出现什么顺序关系,甚至不能保证在两个不同的调用中关系会以相同的方式排序。

    尝试在您的order 中添加一个决胜局:

    Post.order('rating DESC, id')
    

    然后将rating 包含在您正在查看的内容中:

    Post.order('rating desc, id').select('id, rating').map { |p| [ p.id, p.rating ] }
    Post.order('rating desc, id').select('id, rating').limit(1).offset(3).map { |p| [ p.id, p.rating ] }
    #...
    

    这应该会给您带来合理且一致的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-25
      • 1970-01-01
      • 1970-01-01
      • 2021-12-29
      • 2016-06-18
      • 2011-03-11
      相关资源
      最近更新 更多