1

我见过类似的问题,但没有完全符合我需要的答案。如果它在那里,我还没有看到它。我在 Rails 3.1、Ruby 1.9.2 上,部署在 Heroku Cedar 堆栈上(所以我使用的是 postgres)

我有这个模型:

class User
  has_many :orders
end

class Order
  belongs_to :user

  #scope :last_for_each_user, ???
  #scope :first_for_each_user, ???

end

我需要返回所有用户第一个订单的所有订单以及所有用户最后一个订单的所有订单的范围(或方法)。我的第一个直觉是使用 GROUP BY,它在 SQLite3 中对 :last_for_each_user 工作得很好,但是 Postgres 不会让你选择不在 GROUP BY 子句中或作为聚合函数的一部分选择的列,我需要完全形成的订单对象(即所有列、订单。*)。

有任何想法吗?我不想选择整个表并在 Ruby 中对其进行排序。只是感觉不对,而且要记住很多。

4

2 回答 2

1

所以这就是我最终要做的,对于未来的挠头:

scope :last_for_each_user, lambda {
  select("orders.*") & Order.select("max(orders.id) as id").group("orders.user_id")
}
scope :first_for_each_user, lambda {
  select("orders.*") & Order.select("min(orders.id) as id").group("orders.user_id")
}

如果有人有更好的主意,我很乐意听到。感谢整个 SO 社区(即使没有人回应),这是我第一次注册/提出问题,但每次我用谷歌搜索问题时,我都会到这里!

于 2012-07-03T21:10:09.900 回答
0

您可以使用DISTINCT ON()规则仅获取最后一个。这是一个遵循模型结构的示例:

scope :for_users, lambda {|ids, is_first| includes(:user).where("user_id IN (?)", ids).select("DISTINCT ON (users.id) *").order("orders.created_at ?", is_first ? : "ASC" : "DESC") }
scope :last_for_each_users, lambda { |users| for_each_users(users.map{|u| u.id }, false }
scope :first_for_each_users, lambda { |users| for_each_users(users.map{|u| u.id }, true }
于 2012-07-22T19:30:07.343 回答