在PostgreSQL中,将重叠的间隔拆分为较小的、相互接触的间隔

在PostgreSQL中,将重叠的间隔拆分为较小的、相互接触的间隔,sql,postgresql,Sql,Postgresql,我需要一个查询的帮助,该查询应按以下方式拆分一些重叠的日期间隔 例如,如果我们有下表 ---------------------------------------------------------------------- | column_name | value | start_date | end_date | -----------------------------------------------------------------

我需要一个查询的帮助,该查询应按以下方式拆分一些重叠的日期间隔

例如,如果我们有下表

----------------------------------------------------------------------
|   column_name    |    value    |    start_date    |    end_date    |
----------------------------------------------------------------------
|     column1      |    value1   |    03-09-2020    |   26-09-2020   |
----------------------------------------------------------------------
|     column1      |    value2   |    07-09-2020    |   20-09-2020   |
----------------------------------------------------------------------
我在进行以下输出的查询时遇到问题:

----------------------------------------------------------------------
|   column_name    |    value    |    start_date    |    end_date    |
----------------------------------------------------------------------
|     column1      |    value1   |    03-09-2020    |   07-09-2020   |
----------------------------------------------------------------------
|     column1      |    value2   |    07-09-2020    |   20-09-2020   |
----------------------------------------------------------------------
|     column1      |    value1   |    20-09-2020    |   26-09-2020   |
----------------------------------------------------------------------

一种方法是获取所有日期并使用横向联接计算该日期的值:

with dates as (
      select start_date as date
      from t
      union 
      select end_date
      from t
     )
select tt.value, d.date as start_date, lead(d.date) over (order by d.date) as end_date
from dates d left join lateral
     (select t.*
      from t
      where start_date <= d.date and
            end_date > d.date
      order by start_date desc  -- this gets the most recent overlapping value
      limit 1
     ) tt
     on true
order by d.date;
他是一把小提琴


注意:这会添加一个额外的行,其中包含最后的无值时段。如果您不想要,您可以轻松地将其过滤掉。

您如何确定优先级?基于列的名称或值?因此,当我从第一个表中得到结果时,这意味着,列1从2020年9月3日到2020年9月7日具有值1。然后,该值从2020年9月7日切换至值2,直到2020年9月20日,该值才切换回值1至2020年9月26日。我意识到我犯了一个错误。第2列应该是第1列。