gre*_*egb 5 ruby postgresql activerecord ruby-on-rails ruby-on-rails-4
我有一个用户模型和一个卡模型。用户有很多卡,所以卡有一个属性user_id。
我想为每个用户获取最新的单张卡。我已经能够做到这一点:
Card.all.order(:user_id, :created_at)
# => gives me all the Cards, sorted by user_id then by created_at
Run Code Online (Sandbox Code Playgroud)
这让我成功了一半,我当然可以迭代这些行并获取每个用户的第一个行。但这对我来说真的很糟糕,因为我会使用 Ruby 中的数组来做很多这样的事情。
我也可以这样做:
Card.select('user_id, max(created_at)').group('user_id')
# => gives me user_id and created_at
Run Code Online (Sandbox Code Playgroud)
...但我只取回 user_ids 和created_at 时间戳。我无法选择任何其他列(包括 id),因此我返回的内容毫无价值。我也不明白为什么 PG 不允许我选择比上面更多的列而不将它们放入 group_by 或聚合函数中。
我更愿意找到一种仅使用 ActiveRecord 来获取我想要的内容的方法。我也愿意用原始 SQL 编写此查询,但前提是我无法使用 AR 完成它。顺便说一句,我使用的是 Postgres DB,这限制了我的一些选择。
多谢你们。
gre*_*egb -2
我找到了一种性能不佳的解决方案,但适用于非常小的数据集,当时间很短或者它是一个业余爱好项目时:
Card.all.order(:user_id, :created_at).to_a.uniq(&:user_id)
Run Code Online (Sandbox Code Playgroud)
这将获取 AR:Relation 结果,将它们转换为 Ruby Array,然后使用 Proc 对结果执行 Array#uniq。经过一些简短的测试后,#uniq 似乎会保留顺序,因此只要在使用 uniq 之前一切都按顺序进行,就应该没问题。
该功能对时间敏感,所以我现在将使用它,但我将在 @Gene 的响应和链接之后查看原始 SQL 中的某些内容。
| 归档时间: |
|
| 查看次数: |
1712 次 |
| 最近记录: |