Rails activerecord:sum,max和join

时间:2014-03-16 18:09:38

标签: mysql ruby-on-rails activerecord

我有两个模型usersposts。用户可以投票和查看帖子

#users
  id
  name

#posts
  id
  count_votes
  count_views
  users_id
  created_at
  updated_at

我希望过去24小时内收到最多选票和观看次数的用户。最大的观点和选票获胜。

我做了什么 我有这个SQL查询,它很好,但我希望用户拥有最多的投票,这个给我所有用户,我不知道如何添加count_views

select u.name as "Name", sum(p.count_votes)
from posts p 
inner join users u on p.user_id = u.id 
where p.created_at >= DATE_SUB(NOW(), INTERVAL 1 day)
group by user_id;

ActiveRecord版本

Post.select("users.id, sum(posts.count_votes) as nb_votes")
.joins(:user).where("posts.created_at >= ?", 1.day.ago.beginning_of_day)
.group("posts.user_id")

# Results on IRB
=> #<ActiveRecord::Relation [#<Post id: 1>, #<Post id: 3>]> 

如何在这两个总和上组合总和和最大值?有没有办法获得activerecord代码或只有原始SQL?

2 个答案:

答案 0 :(得分:5)

您当前的查询对用户进行分组。因此,您将在输出中为每个用户获取一条记录。通过将输出限制为仅1个记录并按投票+视图总计数排序,您可以获得最高用户。

原始SQL:

select u.id, sum(p.count_votes + p.count_views) total
from posts p 
inner join users u on p.user_id = u.id 
where p.created_at >= DATE_SUB(NOW(), INTERVAL 1 day)
group by u.id
order by total DESC
limit 1 ;

ActiveRecord版本:从用户模型开始,因此您将在输出中获取用户对象而不是Post对象,就像您在问题中提到的那样。

User.select("users.id, sum(posts.count_votes + posts.count_views) as nb_votes")
.joins(:post).where("posts.created_at >= ?", 1.day.ago.beginning_of_day)
.group("posts.user_id").order("nb_votes DESC").limit(1)

答案 1 :(得分:1)

ActiveRecord在使用对象后有意义,在这种情况下,您只需要一个User对象,所以这是您的解决方案:

  sql = %Q(SELECT * FROM users 
  WHERE id = (SELECT users_id FROM posts
    WHERE DATE(created_at) = CURDATE()
    ORDER BY count_votes DESC, count_views DESC
    LIMIT 1
  ) 
  LIMIT 1)

  ActiveRecord::Base.connection.execute(sql)