Third Best Pinball Score

An arcade logs every game played on its pinball machine. To print a bronze-medal sticker, the owner needs the third highest distinct score ever recorded. If several games share a score, that score counts once: with scores 900, 900, 800 and 700, the third highest distinct score is 700.

Return exactly one row with one column named third_best. If there are fewer than three distinct scores (including when no games have been logged), return NULL in that row.

Tables

pinball_runs — One row per game played.

ColumnTypeDescription
run_id (key)INTEGERUnique id of the game
player_tagTEXTThree-letter initials the player entered
pointsINTEGERFinal score of the game

Example

pinball_runs

run_idplayer_tagpoints
1ZAP48200
2KIX51900
3MOO51900
4RAY30150
5ZAP45000
6JET48200

Expected output

third_best
45000

Rows may be returned in any order. Your query also runs against hidden datasets with tricky edge cases.

SQL Path · Subqueries & CTEs · problem 34 of 70 · SQLite

Duplicates matter: work with the distinct scores only.
Sorting distinct scores from high to low and skipping two gives the answer when it exists.
A scalar subquery that finds no row evaluates to NULL; use that to always return one row.

The idea

Sort the distinct scores from highest to lowest, skip two with OFFSET 2 and take one with LIMIT 1. DISTINCT is what makes ties count once. Without it, two games on the same top score would use up two of the three places.

On its own that query returns no row when fewer than three distinct scores exist. Wrapping it as a scalar subquery, SELECT (...) AS third_best, guarantees exactly one row. A scalar subquery that finds nothing becomes NULL.

The alternative peels off the maximum twice: the best score below the best score below the maximum. MAX over an empty set is NULL, and comparing with NULL keeps nothing, so every edge case also ends in a single NULL row. For a general N, DENSE_RANK() is the cleaner tool. RANK() is wrong here because it skips numbers after ties.

Solution

SELECT (
  SELECT DISTINCT points
  FROM pinball_runs
  ORDER BY points DESC
  LIMIT 1 OFFSET 2
) AS third_best;

Another way

SELECT MAX(points) AS third_best
FROM pinball_runs
WHERE points < (
  SELECT MAX(points)
  FROM pinball_runs
  WHERE points < (SELECT MAX(points) FROM pinball_runs)
);

Why common answers fail

Without DISTINCT, repeated scores take up places, so a tie near the top returns the wrong score.

SELECT (
  SELECT points FROM pinball_runs ORDER BY points DESC LIMIT 1 OFFSET 2
) AS third_best;

Returns no row at all when there is no third score, instead of one row containing NULL.

SELECT DISTINCT points AS third_best
FROM pinball_runs
ORDER BY points DESC
LIMIT 1 OFFSET 2;

RANK leaves gaps after ties, so with a tie at the top no score gets rank 3; DENSE_RANK is needed.

SELECT (
  SELECT points
  FROM (SELECT points, RANK() OVER (ORDER BY points DESC) AS r FROM pinball_runs)
  WHERE r = 3
  LIMIT 1
) AS third_best;

What the interviewer is checking

A variation on the N-th highest value: the interviewer checks your handling of duplicates, of the empty answer, and of the difference between RANK and DENSE_RANK.

Mistakes to avoid

  • Forgetting DISTINCT, so ties occupy several places.
  • Returning zero rows instead of one NULL row.
  • Using RANK instead of DENSE_RANK in a window-function solution.

Follow-ups to expect

  • Make N a parameter (LIMIT 1 OFFSET N - 1, or DENSE_RANK() = N).
  • Third best score per player tag (DENSE_RANK() OVER (PARTITION BY player_tag ...)).
  • Return every game that achieved the third best score (join back on points).

In real work

Podium and leaderboard positions, "third cheapest offer" lookups and percentile-style thresholds all ask for the N-th distinct value.

Practice next

Next Post Previous Post
No Comment
Add Comment
comment url