2016-07-29 157 views
2

我已經搜索了幾個星期高和低現在試圖找到我的問題的解決方案。MSSQL 2008合併與分組的連續日期

據我可以確定,我的SQL Server版本(2008r2)是一個限制因素,但是,我肯定有一個解決方案。

我的問題是:

A具有與客戶-狀態 - DateStart-DateEnd-事件ID的形式潛在連續日期的表格。

我需要根據客戶和狀態合併連續的日期 - 狀態字段可以在整個客戶路徑中上下移動。

一些示例性數據如下:

DECLARE @Tbl TABLE([CustomerID] INT 
       ,[Status] INT 
       ,[DateStart] DATE 
       ,[DateEnd] DATE 
       ,[EventID] INT)     

INSERT INTO @Tbl 
VALUES (1,1,'20160101','20160104',1) 
     ,(1,1,'20160104','20160108',3) 
     ,(1,2,'20160108','20160110',4) 
     ,(1,1,'20160110','20160113',7) 
     ,(1,3,'20160113','20160113',9) 
     ,(1,3,'20160113',NULL,10) 
     ,(2,1,'20160101',NULL,2) 
     ,(3,2,'20160109','20160110',5) 
     ,(3,1,'20160110','20160112',6) 
     ,(3,1,'20160112','20160114',8) 

希望的輸出:

Customer | Status | DateStart | DateEnd 
---------+--------+-----------+----------- 
1  | 1  | 2016-01-01| 2016-01-08 
1  | 2  | 2016-01-08| 2016-01-10 
1  | 1  | 2016-01-10| 2016-01-13 
1  | 3  | 2016-01-13| NULL 
2  | 1  | 2016-01-01| NULL 
3  | 2  | 2016-01-09| 2016-01-10 
3  | 1  | 2016-01-10| 2016-01-14 

任何想法/代碼將被大大接收。

感謝,

+0

順序將是不一樣的,所以你要如何我們保存命令 ? – TheGameiswar

+0

已更新的問題包括可在ORDER語句中使用的EventID列 –

+0

如何選擇此「2016-01-13 | NULL'? – NEER

回答

2

通過在輸入表試試這個

DECLARE @Tbl TABLE([CusomerID] INT 
       ,[Status] INT 
       ,[DateStart] DATE 
       ,[DateEnd] DATE 
       ,[EventID] INT)     

INSERT INTO @Tbl 
VALUES (1,1,'20160101','20160104',1) 
     ,(1,1,'20160104','20160108',3) 
     ,(1,2,'20160108','20160110',4) 
     ,(1,1,'20160110','20160113',7) 
     ,(1,3,'20160113','20160113',9) 
     ,(1,3,'20160113',NULL,10) 
     ,(2,1,'20160101',NULL,2) 
     ,(3,2,'20160109','20160110',5) 
     ,(3,1,'20160110','20160112',6) 
     ,(3,1,'20160112','20160114',8) 



;WITH CTE 
AS 
(
    SELECT CusomerID , 
     Status , 
     DateStart , 
     COALESCE(DateEnd, '9999-01-01') AS DateEnd, 
     EventID, 
     ROW_NUMBER() OVER (ORDER BY CusomerID, EventID) RowId, 
     ROW_NUMBER() OVER (PARTITION BY CusomerID, Status ORDER BY EventID) StatusRowId FROM @Tbl 
) 

SELECT 
    A.CusomerID , 
    A.Status , 
    A.DateStart , 
    CASE WHEN A.DateEnd = '9999-01-01' THEN NULL 
    ELSE A.DateEnd END AS DateEnd 
FROM 
(
    SELECT 
     CTE.CusomerID, 
     CTE.Status, 
     MIN(CTE.DateStart) AS DateStart, 
     MAX(CTE.DateEnd) AS DateEnd 
    FROM 
     CTE 
    GROUP BY 
     CTE.CusomerID, 
     CTE.Status, 
     CTE.StatusRowId -CTE.RowId  
) A 
ORDER BY A.CusomerID, A.DateStart 

輸出

CusomerID Status  DateStart DateEnd 
----------- ----------- ---------- ---------- 
1   1   2016-01-01 2016-01-08 
1   2   2016-01-08 2016-01-10 
1   1   2016-01-10 2016-01-13 
1   3   2016-01-13 NULL 
2   1   2016-01-01 NULL 
3   2   2016-01-09 2016-01-10 
3   1   2016-01-10 2016-01-14 
+0

幾乎可行...缺少Customer 1和DateEnds的NULL結束日期不似乎與DateStarts連續.. –

+0

讓我修改它。 – NEER

+0

謝謝NEER - 它比我的距離更近! –