Versuchen Sie Folgendes:
;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
- Der erste CTE ruft die Unterschiede mit dem
lag
ab Funktion (verfügbar ab SQL Server 2012). - Der nächste CTE berechnet, wann die Differenz 1 übersteigt und ordnet alle Datensätze danach einer 'Gruppe' zu, bis die nächste Differenz <> 1 gefunden wird. Dies ist der entscheidende Schritt beim Gruppieren.
- Der letzte Schritt ist die Verwendung von
dense_rank
über den im vorherigen Schritt berechneten Indikator, um die erforderlichen Zeilennummern zu erhalten.
Diese Lösung hat eine Einschränkung darin, dass es fehlschlägt, wenn die Unterschiede nicht in aufsteigender Reihenfolge sind, d. h. wenn Sie zwei weitere Werte in den Beispieldaten wie 52 und 53 haben, werden sie in Gruppe 3 klassifiziert, anstatt eine neue Gruppe zu erstellen.
Aktualisieren :Der folgende Ansatz kann die obige Einschränkung überwinden:
;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
Auch hier bleibt der erste Schritt gleich. Aber in Schritt 2 prüfen wir nur den Übergang zu einem anderen Wert der Differenz zwischen aufeinanderfolgenden Werten, anstatt eine Min/Max-Funktion zu verwenden. Das Ranking verwendet dann eine bedingte Summe, um jedem Wert in den Originaldaten eine Gruppe zuzuweisen.
Dies kann weiter vereinfacht werden zu:
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