Tin*_*n81 27 ruby activerecord ruby-on-rails
在我的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...
如何group使用ActiveRecord 获取每个记录的最新记录?
解决方案可能很简单,但我无法理解这一点.
谢谢你的帮助.
Pat*_*ity 51
在Postgres中,可以使用以下查询来实现.
SELECT DISTINCT ON ("group") * FROM projects
ORDER BY "group", date DESC, id DESC
因为这里的date列可能不是唯一的,所以我添加了一个附加ORDER BY条款id DESC来打破关系,支持具有更高ID的记录,以防组中的两个记录具有相同的日期.您可能希望使用其他列,例如上次更新的日期/时间,这取决于您的用例.
继续,ActiveRecord遗憾的是没有API DISTINCT ON,但我们仍然可以使用纯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这样的其他数据库,遗憾的是这并不方便.有多种解决方案可供选择,例如参见本答案.
我花了一些时间来解决这个问题,并认为我会分享我发现的最干净、最简单的解决方案(假设date或其他排序字段包含唯一值):
Project.group(:group).maximum(:date)
这对我有用
ids = Message.select("MAX(id) AS id").group(:column_name).collect(&:id)
@result = Message.order("created_at DESC").where(:id => ids)
以下基于此链接的解决方案适用于 MySQL,并且可扩展到组表中的所有字段。
Project.select(:group, 'MAX(date) AS date').group(:group)
| 归档时间: | 
 | 
| 查看次数: | 19771 次 | 
| 最近记录: |