2015-09-27 56 views
4

我需要在SQL Server 2012中編號島。島被定義爲在同一ItemId內的DateFromDateTo之間沒有日差距的一組行。SQL Server 2012中的編號島

以下數據集:

CREATE TABLE #Ranges (ItemId INT, DateFrom DATETIME, DateTo DATETIME) 

INSERT INTO #Ranges VALUES (1,'2015-01-31','2015-02-17') 
INSERT INTO #Ranges VALUES (1,'2015-02-18','2015-03-31') 
INSERT INTO #Ranges VALUES (1,'2015-04-14','2015-05-21') 
INSERT INTO #Ranges VALUES (2,'2015-07-12','2015-07-19') 
INSERT INTO #Ranges VALUES (2,'2015-07-20','2015-07-24') 
INSERT INTO #Ranges VALUES (2,'2015-07-26','2015-08-02') 
INSERT INTO #Ranges VALUES (2,'2015-08-03','2015-08-07') 

應編號如下:

ItemId; DateFrom; DateTo;  Number 
1;  2015-01-31; 2015-02-17; 1 
1;  2015-02-18; 2015-03-31; 1 
1;  2015-04-14; 2015-05-21; 2 
2;  2015-07-12; 2015-07-19; 3 
2;  2015-07-20; 2015-07-24; 3 
2;  2015-07-26; 2015-08-02; 4 
2;  2015-08-03; 2015-08-07; 4 

任何幫助非常讚賞。

問候, Przemek

+0

如果你是2012年,你應該使用'DATE',而不是'DATETIME'來存儲數據。 –

+0

的確如此,謝謝。 –

回答

4

如果你想只數得過來的話,我會建議lag(),累計金額:

select t.*, 
     sum(case when datefrom = dateadd(day, 1, prev_dateto 
       then 0 else 1 
      end) over (order by itemId, datefrom) 
from (select t.*, 
      lag(dateto) over (partition by itemid order by datefrom) as prev_dateto 
     from table t 
    ) t; 

case確定新的島嶼開始的地方。累計總和只是總和這個標誌。

+0

完美,簡單而有效。謝謝,戈登。 –

4

您可以使用LAGDENSE_RANK

SqlFiddleDemo

WITH cte AS 
( SELECT 
     * 
     ,LAG(DateFrom) OVER (ORDER BY DateFrom) AS PrevDateFrom 
     ,LAG(DateTo) OVER (ORDER BY DateFrom) AS PrevDateTo  
    FROM Ranges 
) 
SELECT ItemId, DateFrom, DateTo, 
    DENSE_RANK() OVER(ORDER BY CASE WHEN DateFrom = PrevDateTo + 1 THEN PrevDateFrom ELSE DateFrom END) AS Number 
FROM cte