Как я могу подсчитать результат запроса ActiveRecord.group? Цепочка .count возвращает хэш

Я могу использовать следующее:

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

Получить хеши как:

{195=>1, 106=>1, 120=>1, 227=>1, 247=>1, 264=>1, 410=>1}

Можно ли считать эти хэши и вернуть 7 вместо указанного выше результата?

Я знаю, что это не имеет смысла в описанном выше сценарии, и я могу просто сделать это, не используя предложение group. Но я работаю над более сложным запросом, где мне нужно это реализовать. Спасибо заранее.

Ответ 1

Try:

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

Ответ 2

Принятый ответ не является масштабируемым. Использование метода @robbrit в запросе с 25 000 совпадающих пользователей приведет к 25 000 результатов (т.е. Массив с 25 000 элементов) в память, а затем подсчет массива элементов. Вот метод, который будет делать это, не вытягивая все эти данные:

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

Он используется следующим образом:

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

Это работает для меня, используя mysql, btw.

Он был вдохновлен этим парнем: https://github.com/mrbrdo/active_record_group_count/blob/master/lib/active_record_group_count/scope.rb

Ответ 3

Если вы хотите добавить значения хэшей вместе, то:

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

Если вам просто нужно количество клавиш, то:

{key1: 1, key2: 2}.length # => 2

Ответ 5

Как было сказано ранее, ororkedd принятый ответ невелик при работе с большим количеством записей. Я слишком недавно столкнулся с этой проблемой и имею большие таблицы, которые я определенно не хочу загружать в память. Итак, вот что работает для меня.

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

Rails обрабатывает команду users.select как подзапрос. Это работает с Rails 4

Ответ 6

Другой способ, полезный, если значения могут быть > 1.

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