如何使用 Informatica/SQL 为两条记录之间的重叠时间段创建新记录

How to create a new record for the overlapping period between two records using Informatica/SQL

对于以下源数据,需要为重叠期间创建一条新记录,其金额应为重叠记录金额的总和。现有记录的开始日期和结束日期也需要更改,以免重叠。

来源:

ID  StartDate EndDate   Amount
1   1-Jan     31-Jul    100
1   1-Jun     31-Dec    100

预期输出:

ID  StartDate EndDate   Amount
1   1-Jan     31-May    100
1   1-Jun     31-Jul    200
1   1-Aug     31-Dec    100

我如何使用 SQL(IBM DB2)/Informatica 或两者的组合来做到这一点?

注意:不能使用存储过程。

首先要拆分数据,这样只有一列包含金额。我认为这会产生您想要的结果:

select id, dte as StartDate,
       lead(dte) over (partition by id, dte) - 1 day as NextDate,
       sum(sum(amount)) over (partition by id order by dte) as amount
from ((select id, startdate as dte, amount
       from t
      ) union all
      (select id, enddate + 1 day, - amount
       from t
      )
     ) t
group by id, dte;

OLAP 函数确实有助于比较一行与下一行。 UNION 是创建附加行所必需的。以下示例分别处理每种类型的行。

-- normal rows without overlapping
select id, startdate, enddate, amount
  from ( select id, startdate, enddate, amount ,
                lead(startdate) over (partition by id order by startdate) as nextstart
           from t )
 where nextstart > enddate

 union all

-- overlapping time ranges

-- first intervall 
select id, startdate, nextstart - 1 day as enddate, amount
  from ( select id, startdate, enddate, amount ,
                lead(startdate) over (partition by id order by startdate) as nextstart
           from t )
 where nextstart < enddate

union all

-- new middle interval
select id, nextstart as startdate,  enddate, amount + nextamount
  from ( select id, startdate, enddate, amount ,
                lead(startdate) over (partition by id order by startdate) as nextstart,
                lead(amount) over (partition by id order by startdate) as nextamount
          from t )
  where nextstart < enddate

union all

-- last interval
select id, prevend + 1 day as startdate,  enddate, amount 
  from ( select id, startdate, enddate, amount ,
                lag(enddate) over (partition by id order by startdate) as prevend
           from t )
 where startdate < prevend