GROUP_BY 内的活动记录 LIMIT
Posted
技术标签:
【中文标题】GROUP_BY 内的活动记录 LIMIT【英文标题】:Active Record LIMIT within GROUP_BY 【发布时间】:2012-03-03 09:38:33 【问题描述】:场景 我有一张满是帖子的桌子,里面有一张用户表。 我希望能够获取所有帖子并按用户分组,但我希望将限制设置为每个用户 10 个。
class Post < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_many :posts
end
# I thought this might work but it just grabs the first 10 posts and groups them
Post.find(:all, :limit=>10).group_by(&:user)
有什么想法吗?我是否必须为此编写自定义 SQL,或者 Active Record 可以这样做?
【问题讨论】:
这将所有用户的获取限制为 10,而不是您请求的 per-user。如果它需要特定的 SQL 语句才能工作,您可能希望使用 mysql 或您正在使用的任何 RDMBS 对其进行标记。 好的,谢谢我在帖子中添加了 sqlite3 标签 我不认为这是特定于数据库的。 ActiveRecord 可以自行处理。我已经更新了我的答案以反映这一点。 您的解决方案真的可以为每个用户获取 10 个吗?我在下面发布了一些反馈。 【参考方案1】:类似的东西?
Post.group(:user_id).limit(10)
【讨论】:
这不是我需要的 tadman 的评论更好地说明了我想要实现的目标。我希望 activerecord 可以做到这一点,我可以避免编写任何自定义 SQL【参考方案2】:Post.group(:user_id).limit(10)
group_by
不是查询方法,而是Enumerable的方法。
在您的代码中,Post.find(:all, :limit => 10)
在被传递给group_by
之前被转换为Array
。上述方法将查询方法链接在一起,只有在需要时才将它们转换为Array
。
ActiveRecord 处理整个事情。上述方法转化为
SELECT `posts`.* FROM `posts` GROUP BY user_id LIMIT 10
【讨论】:
我在 Rails 控制台中尝试这个,但我不知道它是如何工作的。我正在尝试返回一个哈希值,我可以对其进行迭代以显示每个用户最多 10 个帖子。【参考方案3】:我知道获取每个用户最近 10 个帖子的唯一方法是需要嵌套子查询(可能存在性能问题)或 postgres 样式的横向连接。相当有信心这不能仅使用活动记录来完成,并且需要编写自定义 SQL,而您已表示要避免。
作为一种无需自定义 SQL 即可完成的替代方案,您可以在一个时间窗口(例如过去一个月或一年)内列出每个用户及其帖子,其中包含以下内容:
class User < ActiveRecord::Base
has_many :recent_posts, -> where(posts: created_at 1.month.ago..Time.now) , class_name: 'Post'
end
User.includes(:recent_posts).each do |user|
user.recent_posts
end
它不会为每个用户执行 SQL 查询,因此与纯粹在 ruby 中执行相比性能相对较高。
【讨论】:
以上是关于GROUP_BY 内的活动记录 LIMIT的主要内容,如果未能解决你的问题,请参考以下文章
在 sqlalchemy 中使用 distinct()/group_by() 获取基于每个“名称”列的最新记录
使用 group_by 将第一个创建记录的标识符添加到 select 语句
Codeigniter 中由 distinct() 或 group_by() 过滤的计数结果
R语言dplyr包使用group_by函数arrange函数和filter函数获取每个分组的第一个第N个最后一个记录实战