Rails查询组和计数必须包含零

时间:2015-01-20 02:32:52

标签: ruby-on-rails ruby-on-rails-3

我知道之前已经问过这个问题,但是我已经阅读了很多帖子,并尝试将它们应用到我的情况中,但我无法让它发挥作用。我是一个可以使用一些帮助的初学者。这是我的模特:

class Action < ActiveRecord::Base
  belongs_to :Student
  belongs_to :Meeting
  belongs_to :ClassSection
end

class Meeting < ActiveRecord::Base
  belongs_to :floorplan
  has_many :actions
  belongs_to :class_section

end

我正在尝试为多个会议中的单个学生计算一些行动,包括他/她有0个行动的会议。因此,如果会议表中有两行,ID = 1且ID = 2,并且学生83在actions表中有一个session_id = 1的操作,我的查询将包括 where(:student_id = &gt; 83)某处,应该返回类似

的内容

1 =大于1

2 =大于0

我希望这是有道理的。我知道答案涉及外连接,但我不善于在纯SQL中实现它们,更糟糕的是通过ActiveRecord实现它们。仅供参考我使用的是MYSQL。提前感谢您提供的任何帮助。

2 个答案:

答案 0 :(得分:1)

Meeting
  .joins('LEFT JOIN actions ON meeting_id = meetings.id')
  .where(student_id: 83)
  .group('meetings.id')
  .count('actions.id')

<强>解释

  • .joins 是您需要的直接左/外连接。这意味着“每次会议至少包含一行,即使没有行动”。
  • .group 需要出现在会议ID上,因为这将始终存在,不同的会议应分别进行分组。
  • .count 需要使用操作ID。 COUNT 不会计算空记录,因此没有操作的会议将被计为0。

对于操作的计数,您需要使用Meeting开始查询,这有点奇怪,但是当您想要包含0计数时,这是必要的。否则,SQL无法知道缺少哪些会议!

作为参考,生成的SQL是:

SELECT
  COUNT(actions.id) AS count_actions_id,
  meetings.id AS meetings_id
FROM "meetings" LEFT JOIN actions ON meeting_id = meetings.id
GROUP BY meetings.id

答案 1 :(得分:0)

我认为通过分组

可以正常工作
Meeting.where(student_id: 83).group(:actions).count

这将返回您想要的哈希

{1=>1, 2=>0}