GMB совершенно верно, что необходим рекурсивный CTE. Я предлагаю это в качестве альтернативной формы по двум причинам. Во-первых, потому что он использует SQL Синтаксис сервера, который, по-видимому, является базой данных, используемой в вопросе. Во-вторых, потому что он напрямую вычисляет window
и count
без оконных функций:
with t as (
select t.*, row_number() over (partition by id order by date) as seqnum
from tbl t
),
cte as (
select t.id, t.date, dateadd(day, 90, t.date) as window_end, 1 as window, 1 as count, seqnum
from t
where seqnum = 1
union all
select t.id, t.date,
(case when t.date > cte.window_end then dateadd(day, 90, t.date)
else cte.window_end
end) as window_end,
(case when t.date > cte.window_end then window + 1 else window end) as window,
(case when t.date > cte.window_end then 1 else cte.count + 1 end) as count,
t.seqnum
from cte join
t
on t.id = cte.id and
t.seqnum = cte.seqnum + 1
)
select id, date, window, count
from cte
order by 1, 2;
Здесь - это скрипта db <>.