Tente isto:
;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
- O primeiro CTE obtém as diferenças usando o
lag
função (disponível a partir do SQL Server 2012). - O próximo CTE calcula quando a diferença excede 1 e atribui todos os registros após esse ponto a um 'grupo', até que a próxima diferença <> 1 seja encontrada. Esta é a etapa chave no agrupamento.
- A última etapa é usar
dense_rank
sobre o indicador calculado na etapa anterior para obter os números de linha conforme necessário.
Esta solução tem uma limitação na medida em que falhará se as diferenças não estiverem em ordem crescente, ou seja, se você tiver mais dois valores nos dados de amostra, como 52 e 53, ele os classificará no grupo 3 em vez de criar um novo grupo.
Demonstração
Atualizar :A abordagem abaixo pode superar a limitação acima:
;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
Novamente, o primeiro passo permanece o mesmo. Mas na etapa 2, verificamos apenas a transição para um valor diferente da diferença entre valores sucessivos, em vez de usar uma função min/max. A classificação usa uma soma condicional para atribuir um grupo para cada valor nos dados originais.
Demonstração
Isso pode ser ainda mais simplificado para:
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