Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

tạo phân vùng dựa trên sự khác biệt giữa các chỉ số hàng tiếp theo trong máy chủ sql 2012

Hãy thử điều này:

    ;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 đầu tiên nhận được sự khác biệt bằng cách sử dụng lag chức năng (có sẵn từ SQL Server 2012 trở đi).
  • CTE tiếp theo sẽ tính toán khi sự khác biệt vượt quá 1 và gán tất cả các bản ghi sau điểm đó cho một 'nhóm', cho đến khi tìm thấy sự khác biệt tiếp theo <> 1. Đây là bước quan trọng trong việc phân nhóm.
  • Bước cuối cùng là sử dụng dense_rank vượt chỉ số được tính toán ở bước trước để nhận được số hàng theo yêu cầu.

Giải pháp này có một hạn chế trong đó nó sẽ không thành công nếu sự khác biệt không theo thứ tự tăng dần, tức là nếu bạn có thêm hai giá trị trong dữ liệu mẫu, chẳng hạn như 52 và 53, nó sẽ phân loại chúng thành nhóm 3 thay vì tạo một nhóm mới.

Demo

Cập nhật :Cách tiếp cận dưới đây có thể khắc phục hạn chế trên:

    ;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

Một lần nữa bước đầu tiên vẫn như cũ. Nhưng trong bước 2, chúng tôi chỉ kiểm tra sự chuyển đổi sang một giá trị khác của sự khác biệt giữa các giá trị liên tiếp, thay vì sử dụng hàm min / max. Sau đó, xếp hạng sử dụng một tổng có điều kiện để chỉ định một nhóm cho mỗi giá trị trong dữ liệu gốc.

Bản trình diễn

Điều này có thể được đơn giản hóa thêm thành:

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm cách nào để trả về nhiều hàng dưới dạng một hàng trong T-SQL?

  2. Đếm (*) so với Đếm (Id) trong máy chủ sql 2005

  3. sử dụng biến Bảng với sp_executesql

  4. Trả lại danh sách email được gửi từ thư cơ sở dữ liệu SQL Server (T-SQL)

  5. MS SQL Server:Kiểm tra xem liệu người dùng có thể thực thi một thủ tục được lưu trữ hay không