Zkuste toto:
;with cte as
(select *,
coalesce(row_index - (lag(row_index) over (order by event)),1) diff
from tbl
),
cte2 as
(select *,
(select max(diff)
from cte c
where c.row_index <= d.row_index
) minri
from cte d
)
select event, row_index, minri,
dense_rank() over (order by minri) rn
from cte2
- První CTE získá rozdíly pomocí
lag
funkce (k dispozici od SQL Server 2012 a novější). - Další CTE se vypočítá, když rozdíl překročí 1, a přiřadí všechny záznamy za tímto bodem do „skupiny“, dokud není nalezen další rozdíl <> 1. Toto je klíčový krok při seskupování.
- Posledním krokem je použití
dense_rank
přes indikátor vypočítaný v předchozím kroku, abyste získali požadovaná čísla řádků.
Toto řešení má omezení v tom, že selže, pokud rozdíly nejsou v rostoucím pořadí, tj. pokud máte ve vzorových datech další dvě hodnoty, jako je 52 a 53, zařadí je do skupiny 3 namísto vytvoření nové skupiny.
Aktualizovat :Níže uvedený přístup může překonat výše uvedené omezení:
;with cte as
(select *,
coalesce(row_index - (lag(row_index) over (order by event)),1) diff
from tbl)
,cte2 as
(select *,
diff - coalesce(diff - (lag(diff) over (order by event)),0) tmp
from cte d)
select event,row_index,
1 + sum(case when tmp >= diff then 0 else 1 end) over (order by event) risum
from cte2
První krok opět zůstává stejný. Ale v kroku 2 kontrolujeme pouze přechod na jinou hodnotu rozdílu mezi po sobě jdoucími hodnotami namísto použití funkce min/max. Hodnocení pak používá podmíněný součet k přiřazení skupiny pro každou hodnotu v původních datech.
To lze dále zjednodušit na:
select event, row_index,
sum(case when diff <= 1 then 0 else 1 end) over (order by event) as rb
from
(select *,
row_index - (lag(row_index) over (order by event)) diff
from tbl
) s