Coba ini:
;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
- CTE pertama mendapatkan perbedaan menggunakan
lag
fungsi (tersedia dari SQL Server 2012 dan seterusnya). - CTE berikutnya menghitung saat perbedaan melebihi 1 dan menetapkan semua catatan setelah titik itu ke 'grup', hingga perbedaan berikutnya <> 1 ditemukan. Ini adalah langkah kunci dalam pengelompokan.
- Langkah terakhir adalah menggunakan
dense_rank
atas indikator yang dihitung pada langkah sebelumnya untuk mendapatkan nomor baris sesuai kebutuhan.
Solusi ini memiliki batasan dalam hal itu akan gagal jika perbedaannya tidak dalam urutan yang meningkat yaitu jika Anda memiliki dua nilai lagi dalam data sampel seperti 52 dan 53, itu akan mengklasifikasikannya ke dalam grup 3 alih-alih membuat grup baru.
Perbarui :Pendekatan di bawah ini dapat mengatasi batasan di atas:
;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
Sekali lagi langkah pertama tetap sama. Tetapi pada langkah 2, kami hanya memeriksa transisi ke nilai yang berbeda dari perbedaan antara nilai-nilai yang berurutan, daripada menggunakan fungsi min/maks. Pemeringkatan kemudian menggunakan jumlah bersyarat untuk menetapkan grup untuk setiap nilai dalam data asli.
Ini dapat disederhanakan lebih lanjut menjadi:
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