如何从ActiveRecord中获取每组的最新记录?

在我的Ruby on Rails应用程序中,我有一个这样的数据库结构:

Project.create(:group => "1", :date => "2014-01-01") Project.create(:group => "1", :date => "2014-01-02") Project.create(:group => "1", :date => "2014-01-03") Project.create(:group => "2", :date => "2014-01-01") Project.create(:group => "2", :date => "2014-01-02") Project.create(:group => "2", :date => "2014-01-03") # and so forth... 

如何使用ActiveRecord从每个group获取最新记录?

解决方案可能很简单,但我无法理解这一点。

谢谢你的帮助。

Postgres的

在Postgres中,可以使用以下查询来实现。

 SELECT DISTINCT ON ("group") * FROM projects ORDER BY "group", date DESC, id DESC 

因为date列在这里可能不是唯一的,所以我在id DESC上添加了一个额外的ORDER BY子句来打破关系,支持具有更高ID的记录,以防组中的两个记录具有相同的日期。 您可能希望使用其他列,例如上次更新的日期/时间,这取决于您的用例。

接下来,遗憾的是,ActiveRecord没有用于DISTINCT ON API,但我们仍然可以使用纯SQL和select

 Project.select('DISTINCT ON ("group") *').order(:group, date: :desc, id: :desc) 

或者如果您更喜欢使用ARel而不是使用原始SQL:

 p = Project.arel_table Project.find_by_sql( p.project(p[Arel.star]) .distinct_on(p[:group]) .order(p[:group], p[:date].desc, p[:id].desc) ) 

MySQL的

对于像MySQL这样的其他数据库,遗憾的是这并不方便。 有多种解决方案可供选择,例如参见本答案 。

这对我有用

 ids = Message.select("MAX(id) AS id").group(:column_name).collect(&:id) @result = Message.order("created_at DESC").where(:id => ids) 

像这样的东西?

 Project.select(:group).map(&:group).uniq.each do |grp| puts Project.where(group: grp).order("date DESC").last end 

这将遍历所有组并识别唯一的组。 在您的示例中,它应返回[“1”,“2”]。 然后迭代该数组并选择组ID为1的最后一个Project和组ID为2的最后一个Project。

**更新**

刚刚意识到你说“最新”而不是“最后”需要添加订单以确保最新作品。 最后仍然只拉一个。

 Project.where(:group => "1", :date => "2014-01-01").last 

.last就是你要找的。