Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

utwórz partycję na podstawie różnicy między kolejnymi indeksami wierszy w serwerze sql 2012

Spróbuj tego:

    ;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
  • Pierwsze CTE uzyskuje różnice przy użyciu lag funkcja (dostępna od SQL Server 2012 r.).
  • Następny CTE oblicza, kiedy różnica przekracza 1 i przypisuje wszystkie rekordy po tym punkcie do „grupy”, aż do znalezienia następnej różnicy <> 1. To jest kluczowy krok w grupowaniu.
  • Ostatnim krokiem jest użycie dense_rank nad wskaźnikiem obliczonym w poprzednim kroku, aby uzyskać wymagane numery wierszy.

To rozwiązanie ma ograniczenie oznacza to, że nie powiedzie się, jeśli różnice nie są w kolejności rosnącej, tj. jeśli masz dwie dodatkowe wartości w przykładowych danych, takie jak 52 i 53, zaklasyfikuje je do grupy 3 zamiast tworzyć nową grupę.

Demo

Aktualizacja :Poniższe podejście może przezwyciężyć powyższe ograniczenie:

    ;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

Znowu pierwszy krok pozostaje taki sam. Ale w kroku 2 sprawdzamy tylko przejście do innej wartości różnicy między kolejnymi wartościami, zamiast używać funkcji min/max. Ranking następnie wykorzystuje sumę warunkową do przypisania grupy do każdej wartości w oryginalnych danych.

Demo

Można to jeszcze bardziej uprościć do:

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. Wybierz rekordy między zakresem z innej tabeli

  2. JSON_VALUE dla SQL Server 2012?

  3. Wiele wyników dla jednego pola w połączonym zapytaniu SQL

  4. SQL Server 2016:Utwórz tabelę

  5. Pobierz ostatni dzień miesiąca w SQL