在 PostgresSQL 上按月对具有开始-结束日期的行进行分组

时间:2021-04-21 12:33:36

标签: sql postgresql group-by

我有一个带有 tbl_registration 的数据库,其中的行看起来像

ID | start_date_time | end_date_time | ...
1 | 2021-01-01 14:00:15 | 2021-01-01 14:00:15
2 | 2021-02-01 14:00:15 | null
4 | 2021-05-15 14:00:15 | 2024-01-01 14:00:15
5 | 2019--15 14:00:15 | 2024-01-01 14:00:15

endDate 可以为 null 它包含 500.000 - 1.000.000 条记录

我们想要创建按月分组的年份概览,以显示该月的活动记录数量。因此,如果根据开始和结束日期(部分)在该月内,则按月计算一次注册。

我可以像这样每月查询一次

select  count (id)
from tbl_registration
  where
 (r.end_date_time >= to_timestamp('01/01/2021 00:00:00', 'DD/MM/YYYY HH24:MI:SS')  or r.end_date_time is null )
  and r.start_date_time < to_timestamp('01/02/2021 00:00:00', 'DD/MM/YYYY HH24:MI:SS');

但这迫使我重复这个查询 12 次。 我没有看到一种创造性的方法可以在一个查询中解决这个问题,结果是 12 行,每个月一个

我一直在研究 generate_series 函数,但我不知道如何对这些开始日期和结束日期的比较进行分组

1 个答案:

答案 0 :(得分:1)

Postgres 支持 generate_series() 。 . .所以生成你想要的日期然后构造查询。一种方法是:

select gs.mon, x.cnt
from generate_series('2021-01-01'::date, '2021-12-01'::date, interval '1 month') gs(mon) left join lateral
     (select  count(*) as cnt
      from tbl_registration
      where r.end_date_time >= gs.mon or r.end_date_time is null) and
            r.start_date_time < gs.mon + interval '1 month'
     )  x
     on 1=1;
相关问题