2016-07-29 4 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

거의 작동 ... 고객 1 및 DateEnds에 대한 NULL을 종료 날짜 누락 더 이상 DateStarts와 인접 해 보이는 것 .. –

+0

하자 나는 그것을 수정한다. – NEER

+0

감사합니다 NEER - 내가 가진 것보다 더 가깝습니다! –