I need to find overlapping dates for a table. So the basic structure is ID, PFX, Start date, and end date. So where the PFX for a given ID is overlapping with another PFX for each ID.
I tried this and had no luck. https://www.sqlservercentral.com/forums/topic/how-to-extract-overlapping-date-ranges-from-a-table-of-date-ranges
The highlighted is what I would want to show as an overlap.
x
Drop table #zzz_Overlapping
CREATE TABLE #zzz_Overlapping(
[ID] [varchar](500) NULL,
[PFX] [varchar](500) NULL,
[EFF_DT] [datetime] NULL,
[TERM_DT] [datetime] NULL
) ON [PRIMARY]
GO
insert into #zzz_Overlapping (ID,PFX,EFF_DT,TERM_DT)
values ( 123,'ABDM','1997-06-01','9999-12-31')
insert into #zzz_Overlapping (ID,PFX,EFF_DT,TERM_DT)
values ( 123,'ABDM','1997-10-01','9999-12-31')
insert into #zzz_Overlapping (ID,PFX,EFF_DT,TERM_DT)
values ( 123,'CSM1','1997-11-01','9999-12-31')
insert into #zzz_Overlapping (ID,PFX,EFF_DT,TERM_DT)
values ( 123,'CSM1','1998-01-01','9999-12-31')
insert into #zzz_Overlapping (ID,PFX,EFF_DT,TERM_DT)
values ( 123,'ABDD','1999-01-01','9999-12-31')
insert into #zzz_Overlapping (ID,PFX,EFF_DT,TERM_DT)
values ( 417,'CSM1','2001-06-01','9999-12-31')
insert into #zzz_Overlapping (ID,PFX,EFF_DT,TERM_DT)
values ( 417,'CSM1','2001-10-01','9999-12-31')
insert into #zzz_Overlapping (ID,PFX,EFF_DT,TERM_DT)
values ( 417,'CSM2','2001-11-01','9999-12-31')
select * from #zzz_Overlapping
select CONCAT(ID, PFX) FROM #zzz_Overlapping
SELECT A.*
FROM #zzz_Overlapping A
JOIN #zzz_Overlapping B
ON B.ID = A.ID
AND ((A.EFF_DT BETWEEN B.EFF_DT AND B.TERM_DT)
OR (A.TERM_DT BETWEEN B.EFF_DT AND B.TERM_DT))
WHERE B.EFF_DT != A.EFF_DT OR B.TERM_DT != A.TERM_DT;
SELECT A.ID, A.PFX, A.EFF_DT, A.TERM_DT, B.PFX, B.EFF_DT, B.TERM_DT
FROM #zzz_Overlapping A
INNER JOIN #zzz_Overlapping B
ON B.ID = A.ID
AND B.EFF_DT < A.TERM_DT
AND A.EFF_DT < B.TERM_DT
AND A.EFF_DT < B.EFF_DT;
Added this for some clarification of expected result.
Advertisement
Answer
Improving upon the answer by Gordon, Can you check the following
with data
as (select row_number() over(order by (select null)) as rnk
,*
from #zzz_overlapping
)
select o.*
from data o
where exists (select 1
from data o2
where o2.id = o.id and
o2.PFX = o.PFX and
o2.EFF_DT <= o.TERM_DT and
o2.TERM_DT >= o.EFF_DT and
o2.rnk <> o.rnk
)
dbfiddle link. https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=11f4e9dc6bd96df6f0c8145df0b953a8