我从AR查询中得到一个奇怪的结果。使用sum
给出的结果是预期结果的两倍。
一些背景
@parent.children.size
=> 1
@parent.children
=> [#<Child id: 1, date: "2016-01-01", quantity: 2>]
@parent.children.group_by_month_of_year(:date).count #using groupdate gem
=> {1=>1, 2=>0, 3=>0, 4=>0, 5=>0, 6=>0, 7=>0, 8=>0, 9=>0, 10=>0, 11=>0, 12=>0}
为什么此总和查询返回1 => 4
?
@parent.children.group_by_month_of_year(:date).sum(:quantity)
=> {1=>4, 2=>0, 3=>0, 4=>0, 5=>0, 6=>0, 7=>0, 8=>0, 9=>0, 10=>0, 11=>0, 12=>0}
只有1个quantity
为2的子记录,查询应该返回1 => 2
不应该吗?
我该怎么做呢?
该查询生成以下SQL
SELECT DISTINCT SUM("purchases"."quantity") AS sum_quantity,
EXTRACT(MONTH from date::timestamptz AT TIME ZONE 'Etc/UTC' - INTERVAL '0 second')::integer
AS extract_month_from_date_timestamptz_at_time_zone_etc_utc_interv
FROM "purchases"
INNER JOIN "people" ON "purchases"."person_id" = "people"."id"
INNER JOIN "events" ON "people"."id" = "events"."person_id"
WHERE "events"."location_id" = $1 AND (date IS NOT NULL)
GROUP BY EXTRACT(MONTH from date::timestamptz AT TIME ZONE 'Etc/UTC' INTERVAL '0 second')::integer
[["location_id", 1]]
具有以下关系
class Location
has_many :events
has_many :people, -> { distinct }, through: :events
has_many :purchases, -> { distinct }, through: :people
end
class Event
belongs_to :location
belongs_to :person
end
class Person
has_many :events
has_many :purchases
end
class Purchase
belongs_to :person
end
在更改关系的定义方式后(如下所示),总和查询正在计算正确的结果。
class Location
has_many :events
has_many :people, -> { distinct }, through: :events
def purchases
Purchase.where( person_id: self.people.pluck(:id)
end
end
答案 0 :(得分:0)
当您以这种方式聚合时,在关联中使用distinct是无效的。如果位置和购买之间存在多个连接路径,则distinct将应用于最终聚合结果,而不应用于基础未聚合结果集。
我不确定数据模型是否有效。如果您试图通过个人和事件获得每个地点的销售额,您如何知道购买与特定事件相关联,从而与特定位置相关联?
您不需要直接通过将event_id添加到购买中来将购买链接到此人和活动,或者通过在与购买时间比较的事件上设置时间范围来隐式?
编辑:
在更好地理解你想要做的事情的背景下,这个怎么样......
Purchase.where(person: Person.joins(:events).where(events: {location_id: @location.id}).uniq).
group_by_month_of_year(:date).sum(:quantity)