我需要在过去的几个月里,每月生成一份特定用户创建的所有记录(业务)的报告。我生成了以下查询,并希望它为每个月提供一行。但是,这个用户最近几个月没有创建任何记录(业务),所以我得到了一个空结果[]
我仍然希望每个月都能收到一行,因为我选择了一个使用右外部连接的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)

10-05 20:32