sql >> Database >  >> RDS >> PostgreSQL

Vind de langste reeks perfecte scores per speler

A probleem inderdaad.

Ervan uitgaande:

  • "Streaks" worden niet onderbroken door rijen van andere spelers.
  • Alle kolommen zijn gedefinieerd NOT NULL . (Anders moet je meer doen.)

Dit zou het eenvoudigst en snelst moeten zijn, omdat er maar twee snelle row_number() vensterfuncties :

SELECT DISTINCT ON (player_id)
       player_id, count(*) AS seq_len, min(ts) AS time_began
FROM  (
   SELECT player_id, points, ts
        , row_number() OVER (PARTITION BY player_id ORDER BY ts) 
        - row_number() OVER (PARTITION BY player_id, points ORDER BY ts) AS grp
   FROM   tbl
   ) sub
WHERE  points = 100
GROUP  BY player_id, grp  -- omit "points" after WHERE points = 100
ORDER  BY player_id, seq_len DESC, time_began DESC;

db<>fiddle hier

De kolomnaam ts gebruiken in plaats van time , wat een gereserveerd woord is in standaard SQL. Het is toegestaan ​​in Postgres, maar met beperkingen en het is nog steeds een slecht idee om het als identifier te gebruiken.

De "truc" is om rijnummers af te trekken zodat opeenvolgende rijen in dezelfde groep vallen (grp ) per (player_id, points) . Dan filter die met 100 punten, aggregeer per groep en retourneer alleen het langste, meest recente resultaat per speler.
Basisverklaring voor de techniek:

We kunnen GROUP BY . gebruiken en DISTINCT ON in dezelfde SELECT , GROUP BY wordt voor toegepast DISTINCT ON . Overweeg de volgorde van gebeurtenissen in een SELECT vraag:

Over DISTINCT ON :



  1. Verbinding maken met de Heroku Postgres-database met Asp.Net

  2. Dump sql-bestand naar ClearDB in Heroku

  3. COUNT in een zoekopdracht met meerdere JOINS en een GROUP BY CLAUSULE

  4. Toegang verlenen tot v$ views (v$session ,v$instance)