Essayez ceci :
;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
- Le premier CTE obtient les différences en utilisant le
lag
fonction (disponible à partir de SQL Server 2012). - Le CTE suivant calcule lorsque la différence dépasse 1 et affecte tous les enregistrements après ce point à un « groupe », jusqu'à ce que la différence suivante <> 1 soit trouvée. C'est l'étape clé du regroupement.
- La dernière étape consiste à utiliser
dense_rank
remplacer l'indicateur calculé à l'étape précédente pour obtenir les numéros de ligne nécessaires.
Cette solution a une limitation en ce sens qu'il échouera si les différences ne sont pas dans l'ordre croissant, c'est-à-dire si vous avez deux valeurs supplémentaires dans les données d'échantillon telles que 52 et 53, il les classera dans le groupe 3 au lieu de créer un nouveau groupe.
Mettre à jour :L'approche ci-dessous peut surmonter la limitation ci-dessus :
;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
Encore une fois, la première étape reste la même. Mais à l'étape 2, nous vérifions uniquement la transition vers une valeur différente de la différence entre les valeurs successives, au lieu d'utiliser une fonction min/max. Le classement utilise ensuite une somme conditionnelle pour attribuer un groupe à chaque valeur des données d'origine.
Cela peut être simplifié davantage :
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