PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Znajdź najdłuższą passę doskonałych wyników na gracza

rzeczywiście problem.

Zakładając:

  • „Serie” nie są przerywane rzędami innych graczy.
  • Wszystkie kolumny są zdefiniowane NOT NULL . (W przeciwnym razie musisz zrobić więcej.)

Powinno to być najprostsze i najszybsze, ponieważ wymaga tylko dwóch szybkich row_number() funkcje okien :

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 tutaj

Używanie nazwy kolumny ts zamiast time , czyli słowo zastrzeżone w standardowym SQL. Jest to dozwolone w Postgresie, ale z ograniczeniami i nadal złym pomysłem jest używanie go jako identyfikatora.

"Sztuczka" polega na odjęciu numerów wierszy tak, aby kolejne wiersze należały do ​​tej samej grupy (grp ) za (player_id, points) . Wtedy filtruj te z 100 punktami, agreguj według grupy i zwracaj tylko najdłuższy, najnowszy wynik na gracza.
Podstawowe wyjaśnienie techniki:

Możemy użyć GROUP BY i DISTINCT ON w tym samym SELECT , GROUP BY jest stosowany przed DISTINCT ON . Rozważ sekwencję zdarzeń w SELECT zapytanie:

Informacje o DISTINCT ON :



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak używać funkcji INSERT...ON CONFLICT (UPSERT) w PostgreSQL z flask_sqlalchemy?

  2. Rails - pobierz obiekty obiektów Z duplikatami

  3. Jak pogrupować znaczniki czasu w wyspy (na podstawie arbitralnej luki)?

  4. Jak obniżyć/mieć poprzednią wersję Postgres DB w Postgres.app

  5. Jak zwrócić niestandardowe typy tabel z Npgsql i procedur składowanych?