sql >> Databasteknik >  >> RDS >> Sqlserver

skapa partition baserad på skillnaden mellan efterföljande radindex i sql server 2012

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.

Demo

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.

Demo

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


  1. Hur man hanterar skrivskyddade DB-anslutningar på applikationsnivå

  2. Hur kan jag flytta en SQL Server LocalDb-databas från en dator till en annan?

  3. Välj bara att ha count=2

  4. Pivotera med dynamiska kolumner i Oracle