Rails,PG:Query每个不同的属性值返回一条记录,按关联属性排序

时间:2014-06-04 15:03:31

标签: ruby-on-rails postgresql ruby-on-rails-4 postgresql-9.1

我没有好好写一个Rails查询,返回我正在寻找的东西。建议的,发布的解决方案不允许我按照与我选择的DISTINCT不同的属性进行排序。

在我的情况下:每个用户都可以购买多个订单商品。在同一天甚至可以多次购买同一次旅行(比如他们想要添加朋友)。我想只返回每个唯一的一个OrderItem记录:trip_date_id,然后按该id的start_date排序。

模型结构

OrderItem

  # id            :integer
  # trip_id       :integer
  # trip_date_id  :integer
  # buyer_id      :integer

  belongs_to :trip
  belongs_to :trip_date
  belongs_to :user, :class_name => 'User', :foreign_key => :buyer_id

TripDate

  # id            :integer
  # start_date    :datetime

  has_one     :order_item
  belongs_to  :trip

Trip

  # id            :integer
  # descr         :text

  has_many    :trip_dates
  has_many    :order_items

User
  # id            :integer

  has_many :order_items, :class_name => 'OrderItem', :foreign_key => 'buyer_id'

查询尝试

User.rb

*does not return unique trip_date_ids >
        self.order_items.joins(:trip_date).where(buyer_id: self.id).select("DISTINCT(order_items.trip_date_id), trip_dates.start_date, order_items.*").order("order_items.trip_date_id").order("trip_dates.start_date ASC")


*some postings have suggested this >
    self.order_items.joins(:trip_date).where(buyer_id: self.id).order("order_items.trip_date_id ASC, trip_dates.start_date ASC").select("DISTINCT ON(trip_date_id) order_items.trip_date_id, order_items. *")

但是,最后一个查询不按trip_date.start_date 排序。我想先通过trip_date.start_date进行排序,但是选择trip_date_id进行排序。因为Postgres希望第一个order_by项匹配第一个DISTINCT项,所以我似乎无法做到这两个。有没有人可以解决这个问题而不诉诸.each循环?

2 个答案:

答案 0 :(得分:2)

我的解决方案是使用DISTINCT ON作为唯一的数据库级代码,然后使用sort_by

self.order_items.where(buyer_id: self.id).select("DISTINCT ON (trip_date_id) *").sort_by{|oi| oi.start_date }

答案 1 :(得分:0)

根据Postgres的文档:

  

DISTINCT ON表达式必须与最左边的ORDER BY表达式匹配。 ORDER BY子句通常包含其他表达式,用于确定每个DISTINCT ON组中行的所需优先级。

尝试将trip_dates.id作为查询.order部分中最左侧的表达式传递。另请参阅StackOverflow问题:

Postgres DISTINCT ordering