CMD Guide
HomeDatabasesSQL Practice Problems

Game Play Analysis III

A windowed SUM(games_played) OVER (PARTITION BY player_id ORDER BY event_date) turns each row into a running total because the ORDER BY inside the window silently attaches a frame — RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW — so the engine re-aggregates over “every earlier row of this player plus me,” row by row, without ever collapsing the rows the way GROUP BY would.

Problem

Table Activity with primary key (player_id, event_date):

+--------------+------+
| Column Name  | Type |
+--------------+------+
| player_id    | int  |
| device_id    | int  |
| event_date   | date |
| games_played | int  |
+--------------+------+

For each player and each date they were active, report games_played_so_far — the cumulative number of games that player has played up to and including that date. This is LeetCode 534. Note the shape: the answer has the same number of rows as the input (one per activity record), each annotated with a total. That “same row count” is the tell that you want a window function, not a GROUP BY.

The query

SELECT player_id,
       event_date,
       SUM(games_played) OVER (
           PARTITION BY player_id
           ORDER BY event_date
       ) AS games_played_so_far
FROM Activity;

The OVER (...) clause is the whole mechanism. Read it as three knobs:

Worked trace

Take player 1 with three activity rows and player 2 with one. The engine processes one partition at a time, walks rows in event_date order, and for each row sums games_played over the frame “start-of-partition → current row.”

partitionevent_dategames_playedframe = rows so fargames_played_so_far
player 12016-03-015{5}5
player 12016-05-026{5, 6}11
player 12017-06-251{5, 6, 1}12
player 22016-03-010{0} (new partition, frame resets)0

Each row keeps its identity — player 1 still produces three output rows — but the games_played_so_far column carries the prefix sum. Player 2’s zero-game day correctly reports 0, not NULL: a row with games_played = 0 is still inside the frame.

diagram
diagram

Window vs. GROUP BY — why not just aggregate?

A natural wrong instinct is SELECT player_id, SUM(games_played) ... GROUP BY player_id. That answers a different question. GROUP BY collapses each player’s rows into one total; you lose event_date and you get one number per player, not a per-date prefix. The window function keeps every row and computes a partial sum positioned at that row’s date.

diagram
diagram

Cost and indexing

The planner satisfies the window in roughly three steps: (1) sort or hash to group rows by player_id, (2) sort within each partition by event_date, (3) stream the partition once, maintaining a running accumulator. With the default UNBOUNDED PRECEDING .. CURRENT ROW frame the accumulator never has to look backward or recompute — it just adds the current row to a carried sum, so the streaming pass is O(n) after the sort, and the sort dominates at O(n log n).

Pitfalls

Takeaways


Re-authored and deepened for this guide. Based on LeetCode 534 “Game Play Analysis III.” Window-frame semantics (the implicit RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW default, and RANGE vs ROWS peer behavior) follow the SQL:2003 standard as documented in the PostgreSQL manual, “Window Function Calls” and Section 3.5 “Window Functions,” and Markus Winand’s SQL Performance Explained / use-the-index-luke.com on indexing window ORDER BY. Opaque alt="Image" raster figures replaced with hand-authored inline SVGs; rote per-clause bullets replaced with a traced example, a GROUP BY contrast, and a cost/index discussion.

🤖 Don't fully get this? Learn it with Claude

Stuck on Game Play Analysis III? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Game Play Analysis III** (Databases) and want to truly understand it. Explain Game Play Analysis III from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Game Play Analysis III** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Game Play Analysis III** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Game Play Analysis III** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes