RoR/Postgres查询所有父母的第一个或最后一个子对象
问题描述:
我看过类似的问题,但没有找到与我需要的答案完全匹配的答案。如果它在外面,我还没有看到它。我on Rails的3.1,红宝石1.9.2,部署在Heroku上雪松堆栈(所以我使用的是Postgres)RoR/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中对其进行排序。这只是感觉不对,而且要记住很多东西。
答
所以这里就是我最后做,为未来的头刮管:
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社区(尽管没有人回应),这是我第一次注册/问一个问题,但每次我在谷歌的一个问题,我最终在这里!
答
您可以使用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 }
什么'Order.where(ID:Order.select( “分钟(orders.id)的ID”)组( “orders.user_id”)。)'? – cbliard