2016-09-28 6 views
2

ich kontinuierlich Datum zu kombinieren versuchen umspannt, wann immer sieContinuous Zeitraum T-SQL-

ID_NBR START_DT END_DT 
22 20120101 20120131 
22 20120201 20120731 
22 20120801 20121231 
22 20130201 20131231 
22 20140101 20151231 
22 20160101 20160131 
22 20160201 20160430 
22 20160601 20160630 
22 20160701 99991231 

existieren und wollen das Ergebnis wie unten zu sein:

ID_NBR START_DT END_DT 
22 20120101 20121231 
22 20130201 20160430 
22 20160601 99991231 

Offensichtlich bin ich nicht zu versuchen, so hier Löffel gefüttert werden soll, was ich bisher habe, aber ich glaube wirklich, es einen einfacheren Weg

SELECT 
    s1.ID_NBR, 
    s1.START_DT, 
    MIN(t1.END_DT) AS END_DT, 
    ROW_NUMBER() OVER(ORDER BY s1.START_DT) AS Sequence_ID 
FROM MEM s1 
INNER JOIN MEM t1 
ON t1.ID_NBR=s1.ID_NBR 
AND s1.START_DT <= t1.END_DT 
AND NOT EXISTS (
       SELECT*FROM MEM t2 
         WHERE t2.ID_NBR=t1.ID_NBR 
           AND (t1.END_DT+1) >= t2.START_DT 
           AND t1.END_DT < t2.END_DT 
       ) 
WHERE NOT EXISTS(SELECT * FROM MEM s2 
WHERE s2.ID_NBR=s1.ID_NBR 
AND s1.START_DT > s2.START_DT AND (s1.START_DT-1) <= s2.END_DT)     
GROUP BY s1.ID_NBR,s1.START_DT 
+0

Was ist der Datumstyp von Stat_DT und END_DT? – EricZ

+0

Wie hast du das Ergebnis erhalten? Was ist die Logik? –

+0

Dezimal (38,0) und danke für die Bearbeitung – Fonsi

Antwort

2

In Teradata TD14.10 sein muss, gibt es Eine einfache Möglichkeit, überlappende Zeiträume mit SELECT NORMALIZE zu kombinieren. Die Implementierung basiert auf dem Datentyp PERIOD, der das Startdatum enthält, das Enddatum jedoch nicht. Da Ihre Daten das Enddatum enthält müssen Sie es für die Berechnung einstellen und wieder die Zeit in separaten Spalten wieder zu spalten:

SELECT ID_NBR, 
    Begin(pd), -- get the start date 
    Last(pd) -- adjust the end date 
FROM 
(
    SELECT NORMALIZE 
     ID_NBR, 
     -- periods are [inclusive..exclusive[ 
     PERIOD(START_DT,CASE WHEN END_DT = DATE '9999-12-31' THEN END_DT ELSE END_DT + 1 END) AS pd 
    FROM tab 
) AS dt 

Wenn Sie Daten tatsächlich Decimal(38,0) sind (was völlig falsch ist) Sie werfen müssen, um sie zu Daten zuerst mit

Cast(start_dt - 19000000 AS DATE)