SQL Dynami c Группировка окон времени начала - PullRequest
0 голосов
/ 31 марта 2020

Я хочу написать SQL Запрос на возврат столбца «window_group» ниже, учитывая столбец «date»:

Этот столбец window_group создан так, что ..

  • Каждое окно заканчивается window_length дней после первой даты в окне
  • Новое windows начинается с первой даты после окончания последнего окна
| date      | window_group |
|-----------|--------------|
| 1/1/2020  |     a        |
| 1/2/2020  |     a        |
| 1/5/2020  |     b        |
| 1/7/2020  |     b        |
| 1/12/2020 |     c        |
| 1/13/2020 |     c        |

Ожидаемое sql вывод выше, используя длину окна 3.

Эта диаграмма c может также помочь вам понять:

1  2        5     7             12 13 
|  |        |     |              |  |     
+--+--+--+--+--+--+--+--+--+--+--+--+--+--...
1  2  3  4  5  6  7  8  9  10 11 12 13 14
a  a  a  .  b  b  b  .  .  .  .  c  c  c


window_length: 3

groupings:
a: [1, 2]
b: [5, 7]
c: [12, 13]

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

Любая помощь будет очень ценится!

1 Ответ

1 голос
/ 01 апреля 2020

Это хитрая логика c. Для этого вам нужен рекурсивный CTE:

with t as (
      select t.*, row_number() over (order by date) as seqnum
      from <table> t
     ),
     cte as (
      select t.date, dateadd(day, 3, t.date) as grpend, 1 as grp, t.seqnum
      from t
      where seqnum = 1
      union all
      select t.date,
             (case when t.date <= cte.grpend then cte.grpend else dateadd(day, 3, t.date) end),
             (case when t.date <= cte.grpend then cte.grp else cte.grp + 1 end),
             t.seqnum
      from cte join
           t
           on t.seqnum = cte.seqnum + 1
     )
select *
from cte;
...