Ruby on rails ActiveRecord Count对Rails中group by返回的行进行计数

Ruby on rails ActiveRecord Count对Rails中group by返回的行进行计数,ruby-on-rails,activerecord,ruby-on-rails-2,Ruby On Rails,Activerecord,Ruby On Rails 2,我环顾四周,找不到任何答案。所有答案均涉及未使用分组的计数 背景: 我有一个分页器,它将为ActiveRecord.find提供选项。它添加:limit和:offset选项并执行查询。我还需要计算记录的总数(小于限制),但有时查询包含:group选项和ActiveRecord.count尝试返回group by返回的所有行及其每个计数。我在Rails 2.3.5中进行了这项工作 我希望ActiveRecord.count返回GROUP by返回的行数 下面是一些示例代码,演示了这方面的一个实例(

我环顾四周,找不到任何答案。所有答案均涉及未使用分组的计数

背景: 我有一个分页器,它将为ActiveRecord.find提供选项。它添加:limit和:offset选项并执行查询。我还需要计算记录的总数(小于限制),但有时查询包含:group选项和ActiveRecord.count尝试返回group by返回的所有行及其每个计数。我在Rails 2.3.5中进行了这项工作

我希望ActiveRecord.count返回GROUP by返回的行数

下面是一些示例代码,演示了这方面的一个实例(用于查找所有标记并按带有该标记的帖子数量对其排序):

使用:select选项,Tag.count生成以下SQL:

SELECT count(tags.*, COUNT(*) AS post_count) AS count_tags_all_count_all_as_post_count, tags.id AS tags_id FROM `tags`  INNER JOIN posts_tags  GROUP BY tags.id  ORDER BY COUNT(*) DESC
正如您所看到的,它只是在“tags.*,COUNT(*)周围包装了一个COUNT(),MySQL抱怨计数中的计数

如果不使用:select选项,它将生成以下SQL:

SELECT count(*) AS count_all, tags.id AS tags_id FROM `tags` INNER JOIN posts_tags GROUP BY tags.id ORDER BY COUNT(*)
它按结果集而不是行数返回整个组


有没有办法解决这个问题,或者我必须破解分页器,以使用GROUP BY来解释查询(我将如何处理)?

如果我正确理解您的问题,那么如果您根本不使用Tag.count,它应该可以工作。在select散列中将“COUNT(*)指定为post_COUNT”就足够了。例如:

@tag = Tag.first(options)
@tag.post_count
如您所见,可以从@tag实例访问查询中的post_count值。如果你想得到所有的标签,也许可以这样:

@tags = Tag.all(options)
@tags.each do |tag|
  puts "Tag name: #{tag.name} posts: #{tag.post_count}"
end
更新:

可以使用要计数的属性和参数调用Count:distinct

options = { :select => 'tags.*, COUNT(*) AS post_count',
            :joins => 'INNER JOIN posts_tags',   #Join table for 'posts' and 'tags'
            :group => 'tags.id',
            :order => 'post_count DESC',
            :offset => (page - 1) * per_page,
            :limit => per_page }

@count = Tag.count(:id, :distinct => true, :joins => options[:joins])

@items = Tag.find(options)

看起来您需要单独处理分组查询。不使用组进行计数将返回整数,而使用组进行计数将返回哈希:

Tag.count
  SQL (0.2ms)  SELECT COUNT(*) FROM "tags"
 => 37

Tag.count(:group=>"tags.id")
  SQL (0.2ms)  SELECT COUNT(*) AS count_all, tags.id AS tags_id FROM "tags" 
    GROUP BY tags.id
 => {1=>37}

对于我的情况,解决方法似乎是在执行计数之前,将选项哈希中的:group=>'tags.id'替换为:select=>'DISTINCT tags.id'

count_options = options.clone
count_options.delete(:order)

if options[:group]
  group_by = count_options[:group]
  count_options.delete(:group)
  count_options[:select] = "DISTINCT #{group_by}"
end

@item_count = @type.count(count_options)

如果您使用的是Rails 4或5,那么也可以执行以下操作

Tag.group(:id).count
另一个(黑客)解决方案:

selection = Tag.where(...).group(...)
count = Tag.connection.select_value "select count(*) from (" + selection.to_sql + ") as x"

我要做的是数一数行数。post_计数只是在每个标记旁边列出的内容,就像您在第二个代码段中列出的一样。分页器需要知道将有多少页,因此它必须找到查询返回的记录数,而不受限制。paginator在许多地方都被重用,因此我无法插入特殊代码来修复此问题,我希望保持界面不变。使用其他方案更新了我的答案。我不确定这对我有何帮助。我的问题是,由于GROUP BY子句,Tag.count返回一个完整的结果集。我希望它返回一个整数,这是所有标记的计数,但是使用我用来获取标记的samw查询。正如您已经注意到的,当您使用与计数完全相同的查询时,它将返回分组哈希而不是整数。但实际上,原始查询中唯一需要相同的是:joins散列。我会再做一次更新,看看能否澄清。哦,我现在明白了。我不想过多地处理查询,这样代码就可以处理我抛出的任何查询,但我确实用了类似的方法解决了它(请参阅问题的附加编辑)。我将尝试使用指定的:group=>'column'劫持查询,并将其改为:select=>'DISTINCT column'。如果您发现这样做有任何问题,请告诉我。将:group=>“column”更改为:select=>“DISTINCT column”似乎可以正常工作。
selection = Tag.where(...).group(...)
count = Tag.connection.select_value "select count(*) from (" + selection.to_sql + ") as x"