Skip to content
Advertisement

Find the longest streak of perfect scores per player

I have a the following result from a SELECT query with ORDER BY player_id ASC, time ASC in PostgreSQL database:

I’m trying to find each player’s longest streak where points = 100, with the tiebreaker being whichever streak began most recently. I also need to determine the time at which that player’s longest streak began. The expected result would be:

Advertisement

Answer

A problem indeed.

Assuming:

  • “Streaks” are not interrupted by rows from other players.
  • All columns are defined NOT NULL. (Else you have to do more.)

This should be simplest and fastest as it only needs two fast row_number() window functions:

db<>fiddle here

Using the column name ts instead of time, which is a reserved word in standard SQL. It’s allowed in Postgres, but with limitations and it’s still a bad idea to use it as identifier.

The “trick” is to subtract row numbers so that consecutive rows fall in the same group (grp) per (player_id, points). Then filter the ones with 100 points, aggregate per group and return only the longest, most recent result per player.
Basic explanation for the technique:

We can use GROUP BY and DISTINCT ON in the same SELECT, GROUP BY is applied before DISTINCT ON. Consider the sequence of events in a SELECT query:

About DISTINCT ON:

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement