Prøv dette:
;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ørste CTE får forskellene ved hjælp af
lag
funktion (tilgængelig fra SQL Server 2012 og frem). - Den næste CTE beregner, når forskellen overstiger 1, og tildeler alle poster efter det punkt til en 'gruppe', indtil den næste forskel <> 1 er fundet. Dette er nøgletrinet i gruppering.
- Det sidste trin er at bruge
dense_rank
over indikatoren beregnet i det foregående trin for at få rækkenumrene efter behov.
Denne løsning har en begrænsning i, at det vil mislykkes, hvis forskellene ikke er i stigende rækkefølge, dvs. hvis du har to værdier mere i eksempeldataene, såsom 52 og 53, vil det klassificere dem i gruppe 3 i stedet for at oprette en ny gruppe.
Opdater :Nedenstående tilgang kan overvinde ovenstå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
Igen forbliver det første trin det samme. Men i trin 2 kontrollerer vi kun for overgang til en anden værdi af forskellen mellem successive værdier, i stedet for at bruge en min/max-funktion. Rangeringen bruger derefter en betinget sum til at tildele en gruppe for hver værdi i de originale data.
Dette kan yderligere forenkles til:
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