Island Numbering in SQL Server 2012

I need the number of islands in SQL Server 2012. An island is defined as a set of rows where there are no daily gaps between DateFromand DateTowithin the same ItemId).

The following data set:

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')

should be numbered as follows:

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

Any help is greatly appreciated.

Regards, Przemek

+4
source share
2 answers

If you just want to number them, I would suggest lag()with the total amount:

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;

casedetermines where the new island begins. The total amount simply summarizes this flag.

+4
source

You can use LAGand DENSE_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
+4

Source: https://habr.com/ru/post/1609181/


All Articles