Postgresql-组内的最小/最大日期范围

时间:2020-10-14 21:18:14

标签: sql postgresql datetime window-functions gaps-and-islands

我们有一个事务表,它存储数据的方式与历史表非常相似,只要状态更改(或其他属性)生效,历史表就可以生效。

示例:

  Product | Status   | Start Date | End Date
----------+------- --+------------+-----------
widget a  | active   | 02/01/2020 | 02/30/2020
widget a  | active   | 03/01/2020 | 03/19/2020
widget a  | inactive | 03/20/2020 | 05/01/2020
widget a  | active   | 05/02/2020 | 08/31/2020
widget b  | active   | 02/01/2020 | 05/31/2020
widget b  | inactive | 06/01/2020 | 06/31/2020

我正在尝试根据状态变化的最小日期和最大日期汇总这些数据(如我所说,其他属性也会导致记录更改,但是我只关心状态变化)。因此,在上面的示例中,“小部件a”将具有三个记录:从02/01/2020-03/19/2020有效,从03/20/2020-05/01/2020不活跃,从05/02/2020- 2020年8月31日。可以使用ETL工具轻松完成此操作,但我想将其显示在视图中。

注意性能的最佳方法是什么

这是Postgresql 10

1 个答案:

答案 0 :(得分:1)

这是一个空白问题,您希望将具有相同产品和状态的相邻行组合在一起。

这是一种利用行号之间的差异来构建组的方法:

select product, status, min(start_date) start_date, max(end_date) end_date
from (
    select t.*, 
        row_number() over(partition by product order by start_date) rn1,
        row_number() over(partition by product, status order by start_date) rn2
    from mytable t
) t
group by product, rn1 - rn2