Prova detta:
;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
- Den första CTE får skillnaderna med hjälp av
lag
funktion (tillgänglig från SQL Server 2012 och framåt). - Nästa CTE beräknar när skillnaden överstiger 1 och tilldelar alla poster efter den punkten till en 'grupp', tills nästa skillnad <> 1 hittas. Detta är nyckelsteget i gruppering.
- Det sista steget är att använda
dense_rank
över indikatorn som beräknades i föregående steg för att få de radnummer som krävs.
Den här lösningen har en begränsning genom att det kommer att misslyckas om skillnaderna inte är i ökande ordning, dvs. om du har ytterligare två värden i exempeldata som 52 och 53, kommer det att klassificera dem i grupp 3 istället för att skapa en ny grupp.
Uppdatera :Metoden nedan kan övervinna ovanstående begränsning:
;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
Återigen är det första steget detsamma. Men i steg 2 kontrollerar vi endast för övergång till ett annat värde av skillnaden mellan successiva värden, istället för att använda en min/max-funktion. Rangordningen använder sedan en villkorlig summa för att tilldela en grupp för varje värde i originaldata.
Detta kan ytterligare förenklas till:
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