在Rails'中等效的SQL查询积极记录

时间:2014-07-24 04:25:13

标签: mysql sql ruby-on-rails ruby activerecord

Rails noob here ...我正在尝试在我的rails项目中找到最佳选择。我有这样的SQL查询:

select sum(count) from (select count(user_id) as 'count' from accounts group by user_id having count(user_id) > 2) as A

它所要做的就是获得拥有2个以上帐户的用户数量总和。虽然这个SQL查询本身工作正常,但我正试图找到一种方法将其转换为Active Record。 UsersAccounts是我项目中的rails模型。

3 个答案:

答案 0 :(得分:1)

我假设用户与帐户有很多关系?在这种情况下,您可以执行类似

的操作
 User.find(id).accounts.count  

每次具有特定ID的用户都有> = 2个帐户时,您可以在总计数中加1。

或者你可以做类似

的事情
count = 0
@users = User.all 
@users.each do |user|
   if user.accounts.count >= 2
     count += 1
   end
end

希望这是你正在寻找的东西。

答案 1 :(得分:0)

timmy的解决方案应该有效,但会导致N+1 queries。您可以使用.includes来急切加载您需要的内容,以便最大限度地减少对数据库的查询(我也假设您已经在用户和帐户之间设置了has_many和belongs_to关联)。我相信这将是优化的实施:

users = User.includes(:accounts)
count = 0

users.each do |user|
  count += 1 if user.accounts.count > 2
end

我相信你甚至可以通过链接到某个地方来进一步重构,但我不太确定如何。检查我链接到顶部的文档页面。

希望有所帮助。

答案 2 :(得分:0)

根据您提供的SQL查询,Account model (accounts table)有一个名为user_id的列,您将其用于分组。第一步是按user_id分组,找到用户明智的帐号。这将创建一个类似{ u1: n_acc1, u2: n_acc2 }的哈希值。 select语句选择(key: value) user_id: n_accounts所有n_accounts > 2对。然后,您只需map (value) n_accounts进入一个数组并apply sum就可以了。

Account.group(:user_id).count
       .select{ |user_id, n_accounts| n_accounts > 2 }
       .map{ |user_id, n_accounts| n_accounts }
       .sum

无需使用association and/or eager loading。应该比其他解决方案更快。此外,发出单个数据库查询以查找分组计数,其余所有计算都将在ruby端。