Считайте последовательные месяцы с пробелами

#sql

Вопрос:

Рассмотрим таблицу с двумя столбцами, Номером обращения и Месяцем возникновения:

Номер дела Месяц Наступления
123 201801
123 201802
123 201803
123 201805
123 201806

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

 SELECT CaseNumber, 
       OccurenceMonth, 
       COUNT(*) OVER(PARTITION BY CaseNumber ORDER BY OccurenceMonth) AS ConsecutiveMonths
FROM table
ORDER BY CaseNumber, OccurrenceMonth;
 

Это создает таблицу, которая выглядит так:

Номер дела Месяц Наступления Месяцы Подряд
123 201801 1
123 201802 2
123 201803 3
123 201805 4
123 201806 5

Однако я бы хотел, чтобы подсчет последовательных месяцев был сброшен между месяцами возникновения 201803 и 201805, чтобы это выглядело так:

Номер дела Месяц Наступления Месяцы Подряд
123 201801 1
123 201802 2
123 201803 3
123 201805 1
123 201806 2

Насколько я понимаю, это простое изменение значительно усложнит запрос. Есть какие-нибудь идеи о том, как лучше всего это сделать? Спасибо.

Комментарии:

1. Каков тип данных месяца наступления? Также пометьте базу данных, которую вы используете.

2. @GordonLinoff это преобразованная дата-время в формат YYYYMM. СЛЕВА(ПРЕОБРАЗОВАНИЕ(VARCHAR, время появления, 112), 6)

Ответ №1:

Судя по коду в комментарии, вы, похоже, используете SQL Server.

Наблюдение помогает решить эту проблему. Если вы вычтете последовательность чисел (скажем, «номер строки») из каждой строки, то результат будет постоянным там, где месяцы увеличиваются. Вуаля! Мы можем использовать это наблюдение для реализации решения с использованием оконных функций:

 select t.*,
       row_number() over (partition by case_number
                                       dateadd(month, - seqnum, cast(yyyymm   '01' as date))
                          order by yyyymm
                         ) as consecutive_months
from (select t.*,
             row_number() over (partition by case_number order by yyyymm) as seqnum
      from t
     ) t;
 

Комментарии:

1. Гордон, это сработало идеально. Большое вам спасибо за ваш ответ. Я собираюсь отметить ваш ответ как принятый.