postgresql:在重叠时分割时间段

时间:2017-08-02 15:00:19

标签: postgresql date

我有一个表格,其中包含多个单位的重叠时间段。对于每个单元,我想在每个时间重叠的开始和结束时分割时间段。

国家/地区期间的示例:

cntry     |  startdate    |   enddate    |

A         |  1960-01-01   | 1989-12-31   |

B         |  1955-01-01   | 1974-12-31   |
B         |  1975-01-01   | 1999-12-31   |

期望的输出:

cntry     |  startdate    |   enddate    |

A         |  1960-01-01   | 1974-12-31   |
A         |  1975-01-01   | 1989-12-31   |

B         |  1955-01-01   | 1959-12-31   |
B         |  1960-01-01   | 1974-12-31   |
B         |  1975-01-01   | 1999-12-31   |

另请参阅此illustration以获取说明

这与我之前提到的question密切相关,但无法使用此处使用的解决方案解决。对于这种情况下最佳方法的任何意见或建议都将非常受欢迎!

1 个答案:

答案 0 :(得分:0)

递归CTE将让您分解间隔,然后进一步分解这些间隔。这是一个可以使用给定数据的示例。这有点像黑客,所以你可能想要改进它。

with cuts as (
    select startdate as cut_date from country
    ),
cntry_cuts as (
    select * from country where 1=0
    union
    select * from (
        select cntry, startdate, cast(cuts.cut_date - interval '1 day' as date) as enddate
        from 
            country as c
            cross join cuts
            where cuts.cut_date > startdate and cuts.cut_date < enddate
        union
        select cntry, cuts.cut_date as startdate, enddate
        from country as c 
        cross join cuts
            where cuts.cut_date > startdate and cuts.cut_date < enddate
        union
        select cntry, startdate, enddate
        from country as c cross join cuts
        where (select max(cut_date) from cuts) < enddate
        ) as x
    )
select cntry, startdate, min(enddate)
from cntry_cuts
group by cntry, startdate
order by cntry, startdate;

请注意,递归CTE的第一个非递归部分仅用于建立输出格式;没有原始数据被添加到输出格式,因此WHERE 1=0条件。