【问题标题】:Sql query equivalent in Rails' Active RecordRails 的 Active Record 中等效的 Sql 查询
【发布时间】:2017-04-25 15:30:07
【问题描述】:

Rails noob 在这里...我正在尝试在我的 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 模型。

【问题讨论】:

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


    【解决方案1】:

    我假设 User 与 Accounts 有 has_many 关系?在这种情况下,您可以执行类似

    的操作
     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
    

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

    【讨论】:

    • 虽然这个解决方案看起来不错,但它会为每个用户多次查询数据库。我只想得到总和,我给出的 sql 查询比 rails 方式便宜。
    【解决方案2】:

    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
    

    我相信您甚至可以通过链接 .where 来进一步重构它,但我不太确定如何。检查我在顶部链接到的文档页面。

    希望对您有所帮助。

    【讨论】:

      【解决方案3】:

      根据您提供的 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​​ 端。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多