我需要生成一份报告,说明特定用户在过去几个月每个月创建的所有记录(业务)。我提出了以下查询,并希望它为每个月提供一行。但是,这个用户在这几个月内没有创建任何记录(商家),所以我得到一个空的结果generate_series
。
我仍然期望每个月都能收到一行,因为我使用RIGHT OUTER JOIN选择了start = 3.months.ago
stop = Time.now
new_businesses = Business.select(
"generate_series, count(id) as new").
joins("RIGHT OUTER JOIN ( SELECT
generate_series(#{start.month}, #{stop.month})) series
ON generate_series = date_part('month', created_at)
").
where(created_at: start.beginning_of_month .. stop.end_of_month).
where(author_id: creator.id).
group("generate_series").
order('generate_series ASC')
列,但它并没有发生。
new_businesses = Business.select(
"generate_series as month, count(id) as new").
joins("RIGHT OUTER JOIN ( SELECT
generate_series(#{start.month}, #{stop.month})) series
ON (generate_series = date_part('month', created_at)
AND author_id = #{creator.id}
AND created_at BETWEEN '#{start.beginning_of_month.to_formatted_s(:db)}' AND
'#{stop.end_of_month.to_formatted_s(:db)}'
)
").
group("generate_series").
order('generate_series ASC')
如何更改查询以获取每个月的行而不是空结果?我正在使用PosgreSQL。
更新
此代码有效:
{{1}}
答案 0 :(得分:2)
您的问题出现在where
部分,这会破坏任何外部联接。考虑一下这个例子:
select *
from a right outer join b on (a.id = b.id)
它会返回b
的所有行和a
的关联值,但是:
select *
from a right outer join b on (a.id = b.id)
where a.some_field = 1
将删除a
不存在的所有行。
进行此类演唱的正确方法是将过滤器放入join
查询部分:
select *
from a right outer join b on (a.id = b.id and a.some_field = 1)
或使用子查询:
select *
from (select * from a where a.some_field = 1) as a right outer join b on (a.id = b.id)