sql >> Databáze >  >> RDS >> PostgreSQL

Najděte nejdelší sérii perfektních skóre na hráče

A opravdu problém.

Za předpokladu:

  • "Streaky" nejsou přerušovány řadami od ostatních hráčů.
  • Všechny sloupce jsou definovány NOT NULL . (Jinak musíte udělat více.)

To by mělo být nejjednodušší a nejrychlejší, protože potřebuje pouze dva rychlé row_number() funkce okna :

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 zde

Pomocí názvu sloupce ts místo time , což je rezervované slovo ve standardním SQL. V Postgresu je to povoleno, ale s omezeními a stále je to špatný nápad používat to jako identifikátor.

„Trik“ spočívá v odečtení čísel řádků tak, aby po sobě jdoucí řádky spadaly do stejné skupiny (grp ) za (player_id, points) . Potom filtrujte ty se 100 body, agregujte je podle skupiny a vraťte pouze nejdelší a nejnovější výsledek na hráče.
Základní vysvětlení techniky:

Můžeme použít GROUP BY a DISTINCT ON ve stejném SELECT , GROUP BY se použije před DISTINCT ON . Zvažte sled událostí v SELECT dotaz:

O DISTINCT ON :



  1. ORA-03113:konec souboru na komunikačním kanálu

  2. MySQL:Mnoho tabulek nebo mnoho databází?

  3. Získejte výsledky dotazu na počet s ignorováním příkazu LIMIT

  4. php/mysql. Existuje funkce mysql ke zjištění, zda existují alespoň 2 určitá slova v alespoň jednom poli řádku mysql