PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Намерете най-дългата поредица от перфектни резултати на играч

A проблем наистина.

Приемайки:

  • „Поредиците“ не се прекъсват от редове от други играчи.
  • Всички колони са дефинирани NOT NULL . (В противен случай трябва да направите повече.)

Това трябва да е най-простото и бързо, тъй като се нуждае само от два бързи row_number() функции на прозорец :

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 тук

Използване на името на колоната ts вместо time , което е запазена дума в стандартен SQL. Позволено е в Postgres, но с ограничения и все още е лоша идея да се използва като идентификатор.

„Номерът“ е да се извадят номерата на редовете, така че последователните редове да попадат в една и съща група (grp ) на (player_id, points) . Тогава филтрирайте тези със 100 точки, обобщавайте за група и връщайте само най-дългия, най-нов резултат за играч.
Основно обяснение на техниката:

Можем да използваме GROUP BY и DISTINCT ON в същия SELECT , GROUP BY се прилага преди DISTINCT ON . Разгледайте последователността от събития в SELECT заявка:

Относно 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. PGError:ГРЕШКА:агрегатите не са разрешени в клаузата WHERE на AR заявка на обект и неговите has_many обекти

  2. Мигриране на тригер от Oracle 11g към Postgresql 8.4

  3. Как Cos() работи в PostgreSQL

  4. Как да създадете хистограма в PostgreSQL

  5. java -postgresql последният вмъкнат идентификатор при вмъкване не се получава