2010-11-22 2 views
3

ich für eine Lösung bin, wo ich eine Reihe von Datensätzen von einem Datensatz erstellen, um Daten aus einer anderen Tabelle. Die Tabellendefinition:aufgeteilt Datensatz in mehrere Datensätze auf Start-/Enddatum

DECLARE A AS TABLE 
(
AID BIGINT NOT NULL, 
StartDate DATETIME NOT NULL, 
EndDate DATETIME 
) 

DECLARE B AS TABLE 
(
AID BIGINT NOT NULL, 
StartDate DATETIME NOT NULL, 
EndDate DATETIME NULL 
) 

Die Idee ist, dass, wenn A enthält:

1 | 01-01-2010 | 01-02-2010 
2 | 01-10-2010 | 31-10-2010 

und B enthält:

1 | 01-01-2010 | 15-01-2010 
2 | 15-10-2010 | 20-10-2010 

wir empfangen 5 Datensätze:

1 | 01-01-2010 | 15-01-2010 
1 | 16-01-2010 | 01-02-2010 
2 | 01-10-2010 | 15-10-2010 
2 | 16-10-2010 | 20-10-2010 
2 | 21-10-2010 | 31-10-2010 

Aktuell Wir machen das mit einem Cursor auf A und einem Inne r Schleife Cursor auf B, müssen wir dies in SQLServer (TSQL oder im schlimmsten Fall CLR)

Haben Sie Ideen, wie dies als eine Auswahl schreiben, so dass der Overhead des Cursors verschwindet?

+0

Es ist nicht klar, was die Regeln sind, um die 5 Datensätze zu generieren. Erklären Sie, was Sie in Englisch zu erreichen versuchen – smirkingman

+0

in A gibt es Perioden, in B gibt es 'sub' Perioden, für jede Periode in B müssen wir die Periode in A aufteilen –

Antwort

2
DECLARE @A TABLE (AID BIGINT NOT NULL, StartDate DATETIME NOT NULL, EndDate DATETIME) 
DECLARE @B TABLE (AID BIGINT NOT NULL, StartDate DATETIME NOT NULL, EndDate DATETIME NULL) 

SET DATEFORMAT dmy 
INSERT @A VALUES (1 ,'01-01-2010','01-02-2010') 
INSERT @A VALUES (2 ,'01-10-2010','31-10-2010') 
INSERT @B VALUES (1 ,'01-01-2010','15-01-2010') 
INSERT @B VALUES (2 ,'15-10-2010','20-10-2010') 

;WITH transitions as 
(
    SELECT *, ROW_NUMBER() OVER (PARTITION BY AID ORDER BY startdate) Sequence 
    FROM (
     SELECT A.AID, A.startdate 
     FROM @a A 
     UNION 
     SELECT A.AID, B.startdate + 1 
     FROM @A A 
     INNER JOIN @b B ON B.startdate > A.startdate AND B.startdate < A.enddate 
     UNION 
     SELECT A.AID, B.enddate + 1 
     FROM @A A 
     INNER JOIN @b B ON B.enddate > A.startdate AND B.enddate < A.enddate 
     UNION 
     SELECT A.AID, A.enddate + 1 
     FROM @a A 
     WHERE A.enddate > A.startdate 
    ) T 
) 
SELECT T1.AID, T1.startdate startdate, T2.startdate - 1 enddate 
FROM transitions T1 
INNER JOIN transitions T2 ON T2.AID = T1.AID AND T2.Sequence = T1.Sequence + 1 
ORDER BY T1.AID, T1.Sequence 
Verwandte Themen