GROUP BY和COUNT使用ActiveRecord

Axi*_*xil 27 ruby sql postgresql activerecord ruby-on-rails

参考: 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
Run Code Online (Sandbox Code Playgroud)

这里ActiveModel使用COUNT执行GROUP BY的正确Rails约定是什么?

the*_*tto 55

DistinctGroup 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} 
Run Code Online (Sandbox Code Playgroud)

如上所述,group将返回哈希值.虽然不同只是返回总人数,见下文.

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

  • 4.2+不需要`all`,只需`Person.group(:name).count` (7认同)
  • 对于任何想要重现上面的重复计数查询的人,“Person.distinct(:name).count”现在将返回与“Person.count”相同的结果。这显然不是想要的结果。如今,您需要执行“Person.distinct.count(:name)”才能获得“6”。 (5认同)

小智 6

另外一个选择:

Person.select(:name, 'COUNT(name)').group(:name)
Run Code Online (Sandbox Code Playgroud)

这会生成一个具有属性计数的人员数组


Don*_*ato 5

请注意,接受的答案将返回一个哈希值:

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} 
Run Code Online (Sandbox Code Playgroud)

但是,如果您想在连接中返回计数以及来自不同表的一些列,该怎么办。然后你还需要使用 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
Run Code Online (Sandbox Code Playgroud)

使用第二种方法,您可以获取有关连接关系的其他详细信息,而无需任何其他查询或循环构造。