在没有counter_cache的情况下计算Rails中的两个或更多关联记录

时间:2015-04-13 09:12:02

标签: ruby-on-rails associations left-join

我需要计算用户的2个关联 - 评论和帖子。此外,我需要计算已发布的帖子,已批准和已取消的评论。

我的代码:

    User.where(id: 1) # just for example!
      .select('users.*, COUNT(comments.id) AS comments_count, COUNT(posts.id) AS posts_count, ' +
        'SUM(CASE comments.status WHEN \'approved\' THEN 1 ELSE 0 END) AS cancelled_comments_count, ' +
        'SUM(CASE comments.status WHEN \'cancelled\' THEN 1 ELSE 0 END) AS cancelled_comments_count, ' +
        'SUM(CASE posts.published WHEN true THEN 1 ELSE 0 END) AS published_posts_count')
      .joins('LEFT OUTER JOIN comments ON (comments.user_id = users.id)')
      .joins('LEFT OUTER JOIN posts ON (posts.user_id = users.id)')
      .group('users.id')

问题在于published_posts_countposts_count的值始终等于comments_count(用户有8条评论,1条帖子,1条已批准的帖子,但是published_posts_countposts_count以8(不是1和1)的形式返回。

我做错了什么?

SQL:

SELECT users.*, 
  COUNT(comments.id) AS comments_count,
  COUNT(posts.id) AS posts_count,
  SUM(CASE comments.status WHEN 'cancelled' THEN 1 ELSE 0 END) AS cancelled_comments_count,
  SUM(CASE comments.status WHEN 'approved' THEN 1 ELSE 0 END) AS approved_comments_count,
  SUM(CASE posts.published WHEN true THEN 1 ELSE 0 END) AS published_posts_count
FROM "users"
LEFT OUTER JOIN comments ON (comments.user_id = users.id)
LEFT OUTER JOIN posts ON (posts.user_id = users.id)
GROUP BY users.id

谢谢!

1 个答案:

答案 0 :(得分:1)

您无法获得此查询所期望的结果。我将尝试解释它的工作方式。

根据JOIN声明,它获得一组评论(设置 C:[c1,c2,...,c8] )和一组帖子(设置 P:[ p1] )给定用户(设置 U:[u1] )。因此,您希望在此3中有一组记录(例如 R )。因此,集合C中的每条记录都与集合P中的每条记录相结合,结果记录与来自的记录相结合。设置U. 所以,如果你有1个用户帖子和8个用户评论,R将有1 *(1 * 8)= 8个记录,并且看起来像这样:

u1|p1|c1
u1|p1|c2
...
u1|p1|c8

最后,COUNT和SUM函数应用于这8条记录,你就拥有了它。

<强> PS 在这里使用2个不同的查询(或子查询)是必要的:一个用于计数帖子,另一个用于评论。