Reputation: 313
What I need is to return all records that may overlap each other.
-- Create Temp Table
CREATE TABLE #Overlap
(SubType varchar(50),
Cause varchar(9),
CircuitID varchar(100),
BegDate date,
EndDate date,
AmtSought decimal(11,2),
Remarks varchar(max))
--Insert records
INSERT INTO #Overlap VALUES('Original','201500018','36/KQ--/831670/IP /NUVX/','2016-12-01','2016-12-31',354.41,'Rec 1')
INSERT INTO #Overlap VALUES('Original','201500009','36/VCID/826061/IP/NUVX','2016-08-11','2016-08-12',200.50,'Rec 2')
INSERT INTO #Overlap VALUES('Original','201500018','36/KQ--/831670/IP /NUVX/','2016-11-15','2016-12-14',100.25,'Rec 3')
INSERT INTO #Overlap VALUES('Original','201500018','36/KQ--/831670/IP /NUVX/','2016-12-16','2017-01-15',300.75,'Rec 4')
INSERT INTO #Overlap VALUES('Original','201500018','36/KQ--/831670/IP /NUVX/','2017-01-01','2017-01-01',500.00,'Rec 5')
INSERT INTO #Overlap VALUES('Original','201500009','36/VCID/826061/IP/NUVX','2016-07-01','2016-07-31',100.50,'Rec 6')
My result would look like:
SubType Cause CircuitID BegDate EndDate AmtSought Remarks
------------------- -------------------------- ---------- ---------- --------- --------
Original 201500018 36/KQ--/831670/IP /NUVX/ 2016-11-15 2016-12-14 100.25 Rec 3
Original 201500018 36/KQ--/831670/IP /NUVX/ 2016-12-01 2016-12-31 354.41 Rec 1
Original 201500018 36/KQ--/831670/IP /NUVX/ 2016-12-16 2017-01-15 300.75 Rec 4
Original 201500018 36/KQ--/831670/IP /NUVX/ 2017-01-01 2017-01-01 500.00 Rec 5
I have tried this from a sample code I saw but it is not returning the desired result.
Select * from #Overlap a
Inner Join #Overlap b
on a.SubType = b.SubType
And a.Cause = b.Cause
And a.CircuitID = b.CircuitID
And b.BegDate between a.BegDate and a.endDate
And b.BegDate < a.endDate
Upvotes: 1
Views: 9619
Reputation: 5148
Assuming that your #Overlap table has a primary key (or unique key) TableId
You could use this following query
SELECT * FROM #Overlap o
WHERE EXISTS
(
SELECT 1 FROM #Overlap o2
WHERE o2.SubType = o.SubType
AND o2.Cause = o.Cause
AND o2.CircuitID = o.CircuitID
AND (
o2.BegDate BETWEEN o.BegDate AND o.EndDate
OR o2.EndDate BETWEEN o.BegDate AND o.EndDate
OR o.BegDate BETWEEN o2.BegDate AND o2.EndDate
OR o.EndDate BETWEEN o2.BegDate AND o2.EndDate
)
AND o2.TableId != o.TableId
)
ORDER BY o.SubType, o.Cause, o.BegDate
Demo link: http://rextester.com/KBFX30109
As @HABO suggestion, you also can use to check overlapping
AND o2.BegDate <= o.EndDate
AND o.BegDate <= o2.EndDate
Upvotes: 4
Reputation: 1715
You need to check start overlap and end overlap. In case, startdate is always less than endDate, following query can be used. The CTE is not required if you have some primary key:
; WITH CTE AS
(
SELECT *,
ROW_NUMBER() OVER(
PARTITION BY (SELECT NULL)
ORDER BY (SELECT NULL)
) AS pk FROM #Overlap
)
SELECT a.*, b.pk, b.BegDate, b.endDate FROM CTE a
CROSS JOIN CTE b
WHERE -- Simplify by adding PK
(a.pk <> b.pk)
AND (CASE WHEN (a.BegDate > b.BegDate) THEN a.BegDate ELSE b.BegDate END)
<= (CASE WHEN (a.endDate < b.endDate) THEN a.endDate ELSE b.endDate END)
Upvotes: 4