如何在Rails中编写以下查询?
我需要编写一个查询,只计算以前没有参加事件的个人。如何在Rails中编写以下查询?
下面是模型
class Individual < ActiveRecord::Base
has_many :attendances, dependent: :destroy
has_many :events, through: :attendances
end
class Attendance < ActiveRecord::Base
belongs_to :event
belongs_to :individual
end
class Event < ActiveRecord::Base
has_many :attendances, dependent: :destroy
has_many :individuals, through: :attendances
end
在我看来,我有2个不同的查询。每个查询都会测量每个会计年度的事件出勤率。
查询风云2015:
<%= Event.published.joins(:attendances => :individual).where(
:events => {:fiscal_session => "2014-10-01".."2015-09-30"}
).distinct.count(:individual_id) %>
查询在FY 2016年
<%= Event.published.joins(:attendances => :individual).where(
:events => { :fiscal_session => "2015-10-01".."2016-09-30"}
).distinct.count(:individual_id) %>
的问题是,对于FY 2016查询不会忽视,在2015年财政年度出席
事件的个体我正在使用postgresql,并且我试图编写范围和帮助器方法来筛选出2015年度出席的个人。但我只是无法弄清楚。
例如,下面是FY 2015年:
<%= Individual.joins(attendances: :event).where(
:events => {:fiscal_session => "2014-10-01".."2015-09-30"}
).group('individuals.id').having('count(attendances.id) > 0').count %>
结果是:
{2787=>1, 3469=>1}
这是FY 2016
<%= Individual.joins(attendances: :event).where(
:events => {:fiscal_session => "2015-10-01".."2016-09-30"}
).group('individuals.id').having('count(attendances.id) > 0').count %>
结果是这样的:
{2905=>1, 3444=>1, 2787=>1, 2790=>1, 2858=>1}
正如你所看到的,individual_id 2787
被计数两次。我不想在FY 2016的查询中计入2787
。
什么是通过Rails和ActiveRecord实现所需计数的正确方法?
我认为最好的方法为了完成你想要做的事情就是用两个查询。
ignore_individuals = Event
.published
.joins(attendances: :individual)
.where(
'events.fiscal_session <= ?', '2015-09-30'
)
.pluck(:individual_id)
Event
.published
.joins(attendances: :individual)
.where.not(individual_id: ignore_individuals)
.where(
events: { fiscal_session: "2015-10-01".."2016-09-30" }
).distinct.count(:individual_id)
今天早些时候我采用了这种方式,除了使用范围。该查询的结果与此查询的结果相同: 'Event.published.where(events:{fiscal_session:“2015-10-01”..“2016-09-30”}).distinct.count(: personal_id)' –
对不起,是的。这不适合你想要做的事情。 – jphager2
这是如此接近。我得到这个错误:'列events.individual_id不存在' –
我认为你正在寻找:Individual.includes(:events).where(events: { id: nil }).count
这些谁没有参加任何活动的人。
没错。这会给我一些没有参加过活动的人数。我如何使用它来获得仅在2016年 –
哇出席的人数。好问题:D – kriskova
不积极的,但如果你正在寻找谁已经在2016年参加的活动的个人的数量和你的表有时间戳你,我相信你能做到
Individual.joins(:attendances).where("attendances.created_at > ?", "01-01-2016").count
这会给我2016年所有参加人数的统计。不过,我不想指望2015年出席的任何人。 –
为了验证我理解您的问题,您希望在2016财年参加过一个或多个活动的个人,但是每隔一段时间都参加了零活动?如果这是正确的,我认为您必须将您当前的查询与两个“NOT IN”查询结合起来,以获得2016财年前后的时间段。 – Brad
是的,这正是我想要的计数。我不熟悉NOT IN –