2017-07-06 4 views
1

Was ich brauche ist, alle Datensätze zurückzugeben, die sich gegenseitig überlappen können.Überlappende Daten suchen und überlappende Datensätze zurückgeben

-- 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') 

Mein Ergebnis würde wie folgt aussehen:

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 

ich dies aus einem Beispielcode versucht, habe ich gesehen, aber es ist nicht das gewünschte Ergebnis zurück.

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 

Antwort

1

Unter der Annahme, dass Ihr #Overlap Tabelle einen Primärschlüssel (oder eindeutige Schlüssel) TableId

Sie sich die folgende Abfrage

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 verwenden: http://rextester.com/KBFX30109

Als @ HABO Vorschlag, können Sie auch verwenden, um überlappende

zu überprüfen
+0

Vielen Dank, dass Sie auf den eindeutigen Schlüssel hingewiesen haben. Ich habe es vergessen. Dieser Code funktioniert großartig! –

+0

Tipp: Die allgemeine Überprüfung auf überlappende Bereiche ist 'Start1 <= End2 und Start2 <= End1'. – HABO

+0

Danke @HABO. Es ist so einfach :) – TriV

2

Sie müssen die Überlappung überprüfen und die Überlappung beenden. Falls Startdatum immer kleiner als Enddatum ist, kann folgende Abfrage verwendet werden. Der CTE ist nicht erforderlich, wenn Sie einen Primärschlüssel haben:

; 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) 
+0

Nicht genau das ursprüngliche Ergebnis, das ich wollte, aber Sie gaben mir ein anderes zu berücksichtigendes Ergebnis, indem Sie analysierten, welcher Rekord tatsächlich mit anderen Aufzeichnungen in der Tabelle in Konflikt stand. Vielen Dank. –