Как создать новую запись для перекрывающегося периода между двумя записями с помощью 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 или их комбинацию?

Примечание. Нельзя использовать хранимые процедуры.


person Vikram Reddy    schedule 22.02.2016    source источник


Ответы (2)


Начать стоит с разделения данных, чтобы был только один столбец с суммой. Я думаю, что это дает то, что вы хотите:

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;
person Gordon Linoff    schedule 22.02.2016
comment
Именно то, что я искал. Спасибо. - person Vikram Reddy; 23.02.2016

Функции 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
person MichaelTiefenbacher    schedule 22.02.2016