我需要在过去的几个月里,每月生成一份特定用户创建的所有记录(业务)的报告。我生成了以下查询,并希望它为每个月提供一行。但是,这个用户最近几个月没有创建任何记录(业务),所以我得到了一个空结果[]
。
我仍然希望每个月都能收到一行,因为我选择了一个使用右外部连接的generate_series
列,但是没有发生这种情况。
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')
如何更改查询以获取每个月的行而不是空结果?我在用PosgreSQL。
更新
此代码有效:
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')
最佳答案
您的问题在于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)