sql >> Database teknologi >  >> RDS >> PostgreSQL

Find den længste række af perfekte scoringer pr. spiller

A problem faktisk.

Forudsat:

  • "Streaks" afbrydes ikke af rækker fra andre spillere.
  • Alle kolonner er defineret NOT NULL . (Ellers skal du gøre mere.)

Dette burde være enklest og hurtigst, da det kun behøver to hurtige row_number() vinduesfunktioner :

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 her

Brug af kolonnenavnet ts i stedet for time , som er et reserveret ord i standard SQL. Det er tilladt i Postgres, men med begrænsninger, og det er stadig en dårlig idé at bruge det som identifikator.

"Tricket" er at trække rækkenumre fra, så på hinanden følgende rækker falder i samme gruppe (grp ) pr. (player_id, points) . filtrer dem med 100 point, samlet pr. gruppe og returner kun det længste, seneste resultat pr. spiller.
Grundlæggende forklaring på teknikken:

Vi kan bruge GROUP BY og DISTINCT ON i den samme SELECT , GROUP BY anvendes før DISTINCT ON . Overvej rækkefølgen af ​​hændelser i en SELECT forespørgsel:

Om DISTINCT ON :



  1. Database - Design af en begivenhedstabel

  2. Forlod Deltag den MAX(DATE)

  3. Brug af MySQLi til at INDSÆTTE data i en database

  4. RuntimeError:arbejder uden for applikationskontekst