web-dev-qa-db-fra.com

GROUP BY et COUNT utilisant ActiveRecord

En se référant à ceci: Y a-t-il une différence entre GROUP BY et 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

Quelle est la bonne convention Rails ici pour qu'ActiveModel effectue un GROUP BY avec COUNT?

25
Axil

Distinct et Group By vont vous donner des résultats différents. Pour obtenir les résultats que vous attendez, vous voudrez utiliser

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} 

Vu ci-dessus, le groupe retournera les choses comme un hachage. Bien que distinct renvoie simplement le nombre de personnes au total, voir ci-dessous.

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

Notez que la réponse acceptée renverra un hachage:

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} 

Mais que se passe-t-il si vous souhaitez renvoyer le nombre ainsi que certaines colonnes de différentes tables dans une jointure. Ensuite, vous devez également utiliser la requête ActiveRecord sélectionnée:

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

Avec cette deuxième approche, vous pouvez récupérer des détails supplémentaires sur une relation de jointure sans aucune requête ni construction de boucle supplémentaires.

1
Donato