GROUP BY и COUNT с использованием ActiveRecord

Ссылаясь на это: Есть ли разница между GROUP BY и DISTINCT

Given a table that looks like this:

name
------
barry
dave
bill
dave
dave
barry
john
This query:

SELECT name, count(*) AS count FROM table GROUP BY name;
Will produce output like this:

name    count
-------------
barry   2
dave    3
bill    1
john    1

Какое правильное соглашение Rails здесь для ActiveModel для выполнения GROUP BY с COUNT?

Ответ 1

Distinct и Group By собираются дать вам разные результаты. Чтобы получить ожидаемые результаты, вы захотите использовать

Person.all.group(:name).count
(1.2ms)  SELECT COUNT(*) AS count_all, name AS name FROM "people" GROUP BY "people"."name"
=> {"Dan"=>3, "Dave"=>2, "Vic"=>1} 

Видно, группа вернет вещи как хэш. В то время как различные просто возвращает количество людей в общей сложности, см. Ниже.

Person.all.distinct(:name).count
(0.4ms)  SELECT DISTINCT COUNT(DISTINCT "people"."id") FROM "people"
=> 6 

Ответ 2

Обратите внимание, что принятый ответ вернет хеш:

Tagging.joins(:tag).group(:name).size
   (0.4ms)  SELECT COUNT(*) AS count_all, 'name' AS name FROM 'taggings' INNER JOIN 'tags' ON 'tags'.'id' = 'taggings'.'tag_id' GROUP BY 'name'
 => {"applesauce"=>1, "oranges"=>2} 

Но что делать, если вы хотите вернуть счетчик плюс несколько столбцов из разных таблиц в объединении. Затем вам также нужно использовать запрос select ActiveRecord:

collection = Tagging.select('COUNT(*) as total, taggings.taggable_id, taggings.taggable_type').joins(:tag).where(taggable_type: 'LineItem', taggable_id: ['5cad0dcc3ed1496086000031', '5cad0dcd3ed1496086000081'] ).group(:name)

collection.each do |item|
  puts item.taggable_id
  puts item.total
end

5cad0dcc3ed1496086000031
1
5cad0dcc3ed1496086000031
2

При втором подходе вы можете получить дополнительные сведения об отношениях соединения без каких-либо дополнительных запросов или конструкций цикла.