Sql 根据给定的开放和关闭日期,生成一段时间内的开放票证计数

Sql 根据给定的开放和关闭日期,生成一段时间内的开放票证计数,sql,postgresql,datetime,count,left-join,Sql,Postgresql,Datetime,Count,Left Join,我有一些票据的一组数据,其中datetime记录了票据的打开和关闭时间(或者NULL如果票据仍然打开) 我们希望生成一个数据表,显示在一段时间内打开的票证总数,按日期分组。如下所示: +------------------+------------------+ | date | num_open | +------------------+------------------+ | 2019-09-01 00:00 | 1

我有一些票据的一组数据,其中
datetime
记录了票据的打开和关闭时间(或者
NULL
如果票据仍然打开)

我们希望生成一个数据表,显示在一段时间内打开的票证总数,按日期分组。如下所示:

+------------------+------------------+
|    date          |    num_open      |
+------------------+------------------+
| 2019-09-01 00:00 | 1                |
| 2020-09-02 00:00 | 1                |
| etc...           |                  |
| 2020-01-01 00:00 | 0                |
| 2020-01-02 00:00 | 0                |
| etc...           |                  |
| 2020-03-08 00:00 | 0                |
| 2020-03-09 00:00 | 1                |
| etc...           |                  |
| 2020-04-14 00:00 | 2                |
+------------------+------------------+
请注意,我不确定给定日期的
num_open
是如何考虑的-应该从日期的结束还是开始的角度考虑,即如果在同一日期打开和关闭,该值是否应计为0


这是在Postgres中,所以我考虑使用窗口函数来实现,但试图按日期截断会使它变得复杂。我曾尝试使用
generate_series
函数创建要加入的日期序列,但当我使用聚合函数时,我“丢失”了对单个票证日期时间的访问。

您可以使用
generate_series()
构建日期列表,然后在不等式条件上进行
左连接
,以使表:

select s.dt, count(t.opened_on) num_open
from generate_series(date '2019-09-01', date '2020-09-01', '1 day') s(dt)
left join mytable t
    on s.dt >= t.opened_on and s.dt < coalesce(t.closed_on, 'infinity')
group by s.dt
选择s.dt,计数(t.opened\u on)num\u open
从生成_系列(日期“2019-09-01”、日期“2020-09-01”、“1天”)s(dt)
左联接myt表
在s.dt>=t.opened\u on和s.dt
实际上,这似乎有点接近你想要的:

select s.dt, count(t.opened_on) num_open
from generate_series(date '2019-09-01', date '2020-09-01', '1 day') s(dt)
left join mytable t
    on s.dt >= t.opened_on::date and s.dt < coalesce(t.closed_on::date, 'infinity')
group by s.dt
选择s.dt,计数(t.opened\u on)num\u open
从生成_系列(日期“2019-09-01”、日期“2020-09-01”、“1天”)s(dt)
左联接myt表
在s.dt>=t.opened_on::date和s.dt
select s.dt, count(t.opened_on) num_open
from generate_series(date '2019-09-01', date '2020-09-01', '1 day') s(dt)
left join mytable t
    on s.dt >= t.opened_on::date and s.dt < coalesce(t.closed_on::date, 'infinity')
group by s.dt