选择具有最新创建日期的唯一记录

时间:2016-05-22 01:06:34

标签: ruby-on-rails postgresql greatest-n-per-group

| id    | user_id | created_at (datetime) |
| 1     | 1       | 17 May 2016 10:31:34  |
| 2     | 1       | 17 May 2016 12:41:54  |
| 3     | 2       | 18 May 2016 01:13:57  |
| 4     | 1       | 19 May 2016 07:21:24  |
| 5     | 2       | 20 May 2016 11:23:21  |
| 6     | 1       | 21 May 2016 03:41:29  |

如何获得唯一且最新的created_at user_id记录的结果,在上述情况下记录为5和6?

到目前为止我尝试了什么

到目前为止,我正在尝试使用group_by返回这样的哈希:

Table.all.group_by(&:user_id)

#{1 => [record 1, record 2, record 4, record 6], etc}

并选择具有最长日期的记录?感谢。

更新了解决方案

感谢Gordon的回答,我使用find_by_sql在ror中使用原始sql查询。

@table = Table.find_by_sql("Select distinct on (user_id) *
                            From tables
                            Order by user_id, created_at desc")

#To include eager loading with find_by_sql, we can add this

ActiveRecord::Associations::Preloader.new.preload(@table, :user)

3 个答案:

答案 0 :(得分:4)

在Postrgres中,您可以使用DISTINCT ON

SELECT DISTINCT ON (user_id) *
FROM tables
ORDER BY user_id, created_at DESC;

我不知道如何在红宝石中表达这一点。

答案 1 :(得分:0)

1)从表中提取唯一用户

Table.all.uniq(:user_id)

2)查找每个用户的所有记录。

Table.all.uniq(:user_id).each {|_user_id| Table.where(user_id: _user_id)}

3)选择最新创建的

Table.all.uniq(:user_id).each {|_user_id| Table.where(user_id: _user_id).order(:created_at).last.created_at}

4)以下列形式返回结果:[[id,user_id],[id,user_id] ...]

Table.all.uniq(:user_id).map{|_user_id| [Table.where(user_id: _user_id).order(:created_at).last.id, _user_id]}

这应该返回 [[6,1],[2,5]]

答案 2 :(得分:0)

Table
  .select('user_id, MAX(created_at) AS created_at')
  .group(:user_id)
  .order('created_at DESC')

注意created_atorder调用中作为字符串传入,因为它是聚合函数的结果,而不是列值。