【问题标题】:Splitting interval overlapping more days in PostgreSQL拆分间隔在 PostgreSQL 中重叠更多天
【发布时间】:2018-03-14 10:24:00
【问题描述】:

我有一个包含开始时间戳和持续时间的 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()、范围函数,但我仍然找不到合理的解决方案。是否有任何现有或可行的解决方案?

【问题讨论】:

    标签: sql postgresql intervals overlap


    【解决方案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 在比较时间戳时可能会让您失败...

    【讨论】:

    • 谢谢!我不知道 tsrange (tstzrange) 类型,它对我的​​情况非常有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多