Prova questo:
;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
- Il primo CTE ottiene le differenze utilizzando il
lag
funzione (disponibile da SQL Server 2012 in poi). - Il CTE successivo calcola quando la differenza supera 1 e assegna tutti i record dopo quel punto a un 'gruppo', finché non viene trovata la differenza successiva <> 1. Questo è il passaggio chiave nel raggruppamento.
- L'ultimo passaggio consiste nell'usare
dense_rank
sopra l'indicatore calcolato nel passaggio precedente per ottenere i numeri di riga richiesti.
Questa soluzione ha una limitazione in quanto fallirà se le differenze non sono in ordine crescente, ad esempio se hai altri due valori nei dati di esempio come 52 e 53, li classificherà nel gruppo 3 invece di creare un nuovo gruppo.
Aggiorna :L'approccio seguente può superare la limitazione di cui sopra:
;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
Anche in questo caso il primo passaggio rimane lo stesso. Ma nel passaggio 2, controlliamo solo la transizione a un valore diverso della differenza tra valori successivi, invece di utilizzare una funzione min/max. La classifica utilizza quindi una somma condizionale per assegnare un gruppo per ogni valore nei dati originali.
Questo può essere ulteriormente semplificato in:
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