【问题标题】:Rails, PG: Query returns one record per distinct attribute value, sorts by association attributeRails,PG:查询每个不同的属性值返回一条记录,按关联属性排序
【发布时间】:2014-06-04 15:03:31
【问题描述】:

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

在我的情况下:每个用户都可以购买多个订单商品。甚至可以在同一日期多次购买同一次旅行(比如他们想加一个朋友)。我只想为每个唯一的 :trip_date_id 返回一个 OrderItem 记录,然后按该 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 循环的情况下解决这个问题?

【问题讨论】:

  • 为什么triptrip_date不能合二为一?
  • 每次旅行有多个旅行日期。
  • 阐明了上面代码中的关系。

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    根据 Postgres 文档:

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

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

    Postgres DISTINCT ordering

    【讨论】:

    • 我现在已经这样做了,并审查了那个问题(连同它的改进版本)并提出了新的查询(在我的问题中),但我似乎不能同时按 trip_date 订购.start_date 并按 order_item.trip_date_id 选择不同的。看起来您链接问题中的 OP 也有同样的问题。想法?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-26
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多