How can I count the result of an ActiveRecord .group query? Chaining .count returns a hash

前端 未结 6 1190
萌比男神i
萌比男神i 2021-01-08 00:51

I can use the following :

User.where(\"zip_code = \'48104\'\").group(\'users.id\').count

To get hashes like :

{195=>1, 1         


        
相关标签:
6条回答
  • 2021-01-08 01:08

    As said before by orourkedd the accepted answer is not great when dealing with a large amount of records. I too recently encountered this issue and have large tables that I definitely don't want to load into memory. So here is what works for me.

    users=User.where("zip_code = '48104'").group('users.id')
    user_count=User.where(id: users.select(:id)).count
    

    Rails will handle the users.select part like a subquery. This works with Rails 4

    0 讨论(0)
  • 2021-01-08 01:17

    The accepted answer is not scalable. Using @robbrit's method on a query with 25,000 matching users would pull 25,000 results (ie an array with 25,000 elements) into memory and then count the elements array. Here is a method that will do it without pulling all that data:

    def count_query(query)
      query = "SELECT count(*) AS count_all FROM (#{query.to_sql}) x"
      ActiveRecord::Base.connection.execute(query).first.try(:[], 0).to_i
    end
    

    It is used like this:

    query = User.where("zip_code = '48104'").group('users.id')
    count = count_query(query)
    

    This works for me using mysql, btw.

    It was inspired by this guy: https://github.com/mrbrdo/active_record_group_count/blob/master/lib/active_record_group_count/scope.rb

    0 讨论(0)
  • 2021-01-08 01:18

    If you want to add the values of the hashes together then:

    {key1: 1, key2: 2}.values.inject(:+) # => 3
    

    If you just want the number of keys then:

    {key1: 1, key2: 2}.length # => 2
    
    0 讨论(0)
  • 2021-01-08 01:23

    Since the first count() is returning a hash, use whatever Ruby enumerable operations you wish on it. Example:

    User.where("zip_code = '48104'").group('users.id').count.count
    

    See also:

    • http://ar.rubyonrails.org/classes/ActiveRecord/Calculations/ClassMethods.html#M000292
    • http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-count
    0 讨论(0)
  • 2021-01-08 01:28

    Try:

    User.where("zip_code = '48104'").group('users.id').count.length
    
    0 讨论(0)
  • 2021-01-08 01:32

    Another way, useful if the values can be > 1.

    User.where("zip_code = '48104'").group('users.id').count.values.sum
    
    0 讨论(0)
提交回复
热议问题