拆分间隔在PostgreSQL中重叠更多天

时间:2018-03-14 10:24:01

标签: sql postgresql intervals overlap

我有一个包含开始时间戳和持续时间的PostgreSQL表。

timestamp           | interval
------------------------------
2018-01-01 15:00:00 | 06:00:00
2018-01-02 23:00:00 | 04:00:00
2018-01-04 09:00:00 | 2 days 16 hours

我想要的是将间隔分成每一天,如下所示:

timestamp           | interval
------------------------------
2018-01-01 15:00:00 | 06:00:00
2018-01-02 23:00:00 | 01:00:00
2018-01-03 00:00:00 | 03:00:00
2018-01-04 09:00:00 | 15:00:00
2018-01-05 00:00:00 | 24:00:00
2018-01-06 00:00:00 | 24:00:00
2018-01-07 00:00:00 | 01:00:00

我正在玩generate_series()width_bucket(),范围函数,但我仍然无法找到合理的解决方案。有没有现有的或有效的解决方案?

1 个答案:

答案 0 :(得分:1)

不确定所有边缘情况,但这似乎有效:

t=# with c as (select *,min(t) over (), max(t+i) over (), tsrange(date_trunc('day',t),t+i) tr from t)
, mid as (
select distinct t,i,g,tr
, case when g < t then t else g end tt
from c
right outer join (select generate_series(date_trunc('day',min),date_trunc('day',max),'1 day')  g from c) e on g <@ tr order by 3,1
)
select
  tt
, i
, case when tt+'1 day' > upper(tr) and t < g then upper(tr)::time::interval when upper(tr) - lower(tr) < '1 day' then i else g+'1 day' - tt end
from mid
order by tt;
         tt          |        i        |   case
---------------------+-----------------+----------
 2018-01-01 15:00:00 | 06:00:00        | 06:00:00
 2018-01-02 23:00:00 | 04:00:00        | 01:00:00
 2018-01-03 00:00:00 | 04:00:00        | 03:00:00
 2018-01-04 09:00:00 | 2 days 16:00:00 | 15:00:00
 2018-01-05 00:00:00 | 2 days 16:00:00 | 1 day
 2018-01-06 00:00:00 | 2 days 16:00:00 | 1 day
 2018-01-07 00:00:00 | 2 days 16:00:00 | 01:00:00
(7 rows)

另请注意,timestamp without time zone在比较时间戳时可能会让您失望......