sql >> Database >  >> RDS >> Sqlserver

maak een partitie op basis van het verschil tussen opeenvolgende rij-indexen in sql server 2012

Probeer dit:

    ;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
  • De eerste CTE krijgt de verschillen met behulp van de lag functie (beschikbaar vanaf SQL Server 2012).
  • De volgende CTE berekent wanneer het verschil groter is dan 1 en wijst alle records daarna toe aan een 'groep', totdat het volgende verschil <> 1 wordt gevonden. Dit is de belangrijkste stap bij het groeperen.
  • De laatste stap is het gebruik van dense_rank over de indicator berekend in de vorige stap om de rijnummers te krijgen zoals vereist.

Deze oplossing heeft wel een beperking in die zin dat het zal mislukken als de verschillen niet in oplopende volgorde zijn, d.w.z. als u nog twee waarden in de voorbeeldgegevens hebt, zoals 52 en 53, zal het deze in groep 3 classificeren in plaats van een nieuwe groep te maken.

Demo

Bijwerken :De onderstaande aanpak kan de bovenstaande beperking overwinnen:

    ;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

Ook hier blijft de eerste stap hetzelfde. Maar in stap 2 controleren we alleen op overgang naar een andere waarde van het verschil tussen opeenvolgende waarden, in plaats van een min/max-functie te gebruiken. De rangschikking gebruikt vervolgens een voorwaardelijke som om een ​​groep toe te wijzen voor elke waarde in de oorspronkelijke gegevens.

Demo

Dit kan verder worden vereenvoudigd tot:

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. Hoe een bij te werken record met JSON-kolom in PostgreSQL in te voegen met JOOQ?

  2. Heeft u al een andere mysqld-server op poort:3306 Ubuntu

  3. MySQL-status weergeven - actieve of totale verbindingen?

  4. Probleem met postgresql en pgadmin docker-containers