首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用于对Rails中group by返回的行进行计数的ActiveRecord计数

用于对Rails中group by返回的行进行计数的ActiveRecord计数
EN

Stack Overflow用户
提问于 2011-02-22 09:34:17
回答 5查看 34.3K关注 0票数 21

我环顾四周,找不到任何答案。所有涉及的答案不是使用 BY的计数。

背景:我有一个分页器,它将接受ActiveRecord.find的选项。它添加了:limit和:offset选项并执行查询。我还需要计算记录的总数(减去限制),但有时查询包含一个:group选项,ActiveRecord.count会尝试返回GROUP by返回的所有行以及它们的每个计数。我在Rails 2.3.5中实现了这一点。

我想让ActiveRecord.count返回GROUP BY返回的行数。

下面是一些示例代码,演示了其中的一个实例(用于查找所有标签,并根据带有该标签的帖子数量对它们进行排序):

代码语言:javascript
复制
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' }

@count = Tag.count(options)

options = options.merge { :offset => (page - 1) * per_page, :limit => per_page }

@items = Tag.find(options)

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

代码语言:javascript
复制
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:

代码语言:javascript
复制
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结果集,而不是行数。

有没有办法绕过这一点,或者我必须修改分页器来处理带有GROUP BYs的查询(我该怎么做)?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-02-22 21:00:11

针对我的情况的解决方法似乎是在执行计数之前在选项散列中将:group => 'tags.id‘替换为:select => 'DISTINCT tags.id’。

代码语言:javascript
复制
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)
票数 9
EN

Stack Overflow用户

发布于 2011-02-22 10:33:58

看起来你需要单独处理分组的查询。不使用group进行计数将返回一个整数,而使用group进行计数将返回一个散列:

代码语言:javascript
复制
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}
票数 23
EN

Stack Overflow用户

发布于 2014-09-28 01:20:37

如果您使用的是Rails 4或5,您还可以执行以下操作。

代码语言:javascript
复制
Tag.group(:id).count
票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5073170

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档