I have a requirement where I will have to split overlapping records on a given table with 2 date fields.
Consider this to be my input table TableT.
| ID | EFFECTIVE_DATE | END_DATE |
|---|---|---|
| JKL | 2016-01-01 | 2016-12-31 |
| JKL | 2016-04-01 | 2016-12-31 |
| JKL | 2016-01-01 | 2016-03-04 |
| JKL | 2016-04-01 | 2016-12-31 |
| JKL | 2016-01-01 | 2016-12-31 |
I would want my output to look like below. I need to achieve this in both SQL Server and Oracle\DB2 so I am looking for a generic solution.
| ID | EFFECTIVE_DATE | END_DATE |
|---|---|---|
| JKL | 2016-01-01 | 2016-03-04 |
| JKL | 2016-03-05 | 2016-03-31 |
| JKL | 2016-04-01 | 2016-12-31 |
This is what I have tried
With EndDates as (
select END_DATE as END_DATE,TRIM(ID) as ID FROM TableT
union all
select ADD_DAYS(EFFECTIVE_DATE, -1) as END_DATE,TRIM(ID) as ID FROM TableT
), Periods as (
select ID as ID,MIN(EFFECTIVE_DATE) as EFFECTIVE_DATE,
(select MIN(END_DATE) from EndDates e
where e.ID = t.ID and
e.END_DATE >= MIN(EFFECTIVE_DATE)) as END_DATE
from
TableT t
group by ID),
EXTN_PERIOD as (select p.ID as ID, ADD_DAYS(p.END_DATE, 1) as EFFECTIVE_DATE,e.END_DATE as END_DATE
from
Periods p
inner join
EndDates e
on
p.ID = e.ID and
p.END_DATE < e.END_DATE
where
not exists (select * from EndDates e2 where
e2.ID = p.ID and
e2.END_DATE > p.END_DATE and
e2.END_DATE < e.END_DATE)
)
select * from EXTN_PERIOD
union
select * from PERIODS
It works partially fine but does not give me the desired output.
This is what the output I get when I run the above query:
| ID | EFFECTIVE_DATE | END_DATE |
|---|---|---|
| JKL | 2016-01-01 | 2016-03-04 |
| JKL | 2016-03-05 | 2016-03-31 |
Thanks in advance!