2016-01-13 1 views
1

ПроблемаПолучить список уникальных кодов, которые являются последовательными с вплоть до 6-дневного буфера

Каковы начальные и конечные даты кода работает?

Я знаю, что это похоже на другие Пробелы и проблемы острова уже здесь, но я не нашел вопрос, который осложняется вопросами followingtwo:

  • код может начинаться и заканчиваться более чем один раз
  • код может работать с вплоть до 6 дней пробелов (Это будет объяснено далее ниже)

данных

Это данные T-SQL, что у меня есть:

Table 

Code  | Date   
-------------------------------- 
1000  | 01-31-2015  
1000  | 02-01-2015  
1000  | 02-02-2015  
1000  | 02-03-2015  
1000  | 02-09-2015  
1000  | 02-10-2015  
1000  | 02-17-2015  
1001  | 02-01-2015  
1001  | 02-02-2015  
1001  | 02-04-2015  
1001  | 02-05-2015  
1001  | 02-12-2015  
1001  | 02-19-2015 

Идеальное решение

То, что я хочу, чтобы мой SQL запрос, чтобы вернуть это:

Code  | StartDate  | EndDate  | Run 
-------------------------------------------------------- 
1000  | 01-31-2015 | 02-10-2015 | 1 
1000  | 02-17-2015 | 02-17-2015 | 2 
1001  | 02-01-2015 | 02-05-2015 | 3 
1001  | 02-12-2015 | 02-12-2015 | 4 
1001  | 02-19-2015 | 02-19-2015 | 5 

Чтобы объяснить далее, давайте возьмем пример:

Код 1000 работает в последовательные дни с 01-31-2015 по 02-03-2015. После этого пробел 6 дней, пока он не будет работать с 02-09-2015 по 02-10-2015. Поскольку разрыв в 6 дней является приемлемым, дата начала этого прогона определяется как 01-31-2015, а дата окончания - 02-03-2015.

Однако, напротив, код 1001 работает 02-12-2015 и 02-19-2015. Поскольку между ними существует разрыв в 7 дней, они не считаются находящимися в одном и том же режиме.

Вся помощь очень благодарна, поэтому большое вам спасибо!

ответ

0

Вам нужно определить, где начинаются группы. В SQL Server 2012+ для этой цели вы можете использовать lag(). Затем, накапливая количество запусков перед данной строкой, у вас есть группа. И, с группой, вы можете агрегировать.

Это выглядит следующим образом:

select code, min(date) as startdate, max(date) as enddate, 
     row_number() over (partition by code order by min(date)) as run 
from (select t.*, 
      sum(IsGroupStart) over (partition by code order by date) as grp 
     from (select t.*, 
        (case when dateadd(day, -6, date) > 
           lag(date) over (partition by code order by date) 
         then 1 else 0 
        end) as IsGroupStart 
      from t 
      ) t 
    ) t 
group by grp, code; 
+0

Я редактировал код в линии 2: ROW_NUMBER() OVER (ORDER BY mediaCode) в перспективе, чтобы получить уникальный идентификатор для каждой строки, но в противном случае это было прекрасно! Благодарю вас @ Gordon! – Bhavik