2016-09-28 39 views
2

我試圖連續日期跨度相結合時,他們存在連續日期跨度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 

,並希望得到的結果是象下面這樣:

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

很顯然,我並不想這是我迄今爲止,但我真的認爲必須有一個更簡單的方式

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

Stat_DT和END_DT的日期類型是什麼? – EricZ

+0

你是如何得到結果集的?什麼是邏輯? –

+0

十進制(38,0)並感謝您的編輯 – Fonsi

回答

2

在Teradata TD14.10有使用SELECT NORMALIZE來組合重疊期的簡單方法。該實現基於PERIOD數據類型,其中包括開始日期,但不包括結束日期。當你的數據包括結束日期,你必須調整它的計算,並再次重新分割在單獨列上期:

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 

如果您日期實際上是Decimal(38,0)(這是完全錯誤的),你需要將它們轉換成首先使用日期

Cast(start_dt - 19000000 AS DATE)