Sign in to run and submit your work
Reading is open to everyone. Running code and saving drafts need an account so your work is yours and comes back on your next visit.
or
CODE WORKSPACE
The app wants to show every listener the first track they ever played next to their most recent one. played_at orders the plays, and stream_tracks holds the title.
Return one row per listener who has played something, ordered by user_id.
Result columns · in this order
user_id | The listener. |
first_track | Title of their earliest play. |
last_track | Title of their most recent play. |
How to approach it
Both answers come from the ends of one ordered partition — say how far the window reaches.
Sample input
| play_id | user_id | track_id | played_at | ms_played | device |
|---|---|---|---|---|---|
| 1 | u1 | t1 | 2026-01-05 20:00:00 | 210000 | mobile |
| 2 | u1 | t2 | 2026-01-05 20:04:00 | 180000 | mobile |
| 3 | u1 | t1 | 2026-01-05 20:08:00 | 150000 | mobile |
| 4 | u1 | t9 | 2026-01-05 21:10:00 | 200000 | mobile |
| 5 | u2 | t3 | 2026-01-06 07:00:00 | 240000 | desktop |
| 6 | u2 | t4 | 2026-01-06 07:10:00 | 195000 | desktop |
| 7 | u2 | t3 | 2026-01-06 09:00:00 | 30000 | desktop |
| 8 | u3 | t5 | 2026-01-09 22:00:00 | 300000 | mobile |
| 9 | u3 | t6 | 2026-01-09 22:06:00 | 270000 | mobile |
| 10 | u3 | t5 | 2026-01-10 22:00:00 | 300000 | mobile |
| 11 | u4 | t7 | 2026-01-15 17:00:00 | 225000 | mobile |
| 12 | u4 | t8 | 2026-01-15 17:04:00 | 250000 | mobile |
| 13 | u5 | t1 | 2026-01-20 06:30:00 | 210000 | desktop |
| 14 | u5 | t3 | 2026-01-20 06:34:00 | 240000 | desktop |
| 15 | u4 | t7 | 2026-02-02 17:00:00 | 225000 | mobile |
| 16 | u1 | t1 | 2026-02-03 19:00:00 | 210000 | desktop |
| 17 | u1 | t5 | 2026-02-03 19:05:00 | 300000 | desktop |
| 18 | u5 | t5 | 2026-02-05 06:30:00 | 300000 | desktop |
| 19 | u5 | t7 | 2026-02-05 07:15:00 | 225000 | desktop |
| 20 | u2 | t10 | 2026-02-11 12:00:00 | 165000 | mobile |
| 21 | u2 | t3 | 2026-02-11 12:03:00 | 240000 | mobile |
| 22 | u3 | t6 | 2026-02-14 21:00:00 | 270000 | desktop |
| 23 | u3 | t5 | 2026-02-14 21:05:00 | 120000 | desktop |
| 24 | u6 | t2 | 2026-02-18 13:00:00 | 180000 | mobile |
| 25 | u6 | t1 | 2026-02-18 13:03:00 | 210000 | mobile |
| 26 | u5 | t2 | 2026-03-01 09:00:00 | 180000 | mobile |
| 27 | u5 | t9 | 2026-03-01 09:03:00 | 200000 | mobile |
| 28 | u1 | t9 | 2026-03-02 08:30:00 | 60000 | mobile |
| 29 | u2 | t4 | 2026-03-05 18:00:00 | 100000 | mobile |
| 30 | u3 | t6 | 2026-03-08 20:00:00 | 270000 | mobile |
| 31 | u4 | t8 | 2026-03-11 16:00:00 | 20000 | mobile |
| 32 | u6 | t2 | 2026-03-15 13:00:00 | 90000 | mobile |
| 33 | u8 | t10 | 2026-03-20 11:00:00 | 165000 | mobile |
| 34 | u8 | t4 | 2026-03-20 11:03:00 | 195000 | mobile |
| 35 | u8 | t10 | 2026-03-20 11:04:00 | 165000 | mobile |
| 36 | u8 | t9 | 2026-03-20 11:07:00 | 200000 | mobile |
36 rows — scroll inside the table to see them all.
| track_id | title | artist | genre | duration_ms |
|---|---|---|---|---|
| t1 | Northern Lights | Aurora Ridge | indie | 210000 |
| t2 | Paper Boats | Aurora Ridge | indie | 180000 |
| t3 | Static Bloom | Kite Machine | electronic | 240000 |
| t4 | Night Signal | Kite Machine | electronic | 195000 |
| t5 | Slow Harbour | Marisol | jazz | 300000 |
| t6 | Blue Hour | Marisol | jazz | 270000 |
| t7 | Copper Wire | Fenpost | rock | 225000 |
| t8 | Ash and Ember | Fenpost | rock | 250000 |
| t9 | Glass Field | Aurora Ridge | indie | 200000 |
| t10 | Quiet Riot Hour | Kite Machine | electronic | 165000 |
10 rows — all rows shown.
Expected output
| user_id | first_track | last_track |
|---|---|---|
| u1 | Northern Lights | Glass Field |
| u2 | Static Bloom | Night Signal |
| u3 | Slow Harbour | Blue Hour |
| u4 | Copper Wire | Ash and Ember |
| u5 | Northern Lights | Glass Field |
| u6 | Paper Boats | Paper Boats |
| u8 | Quiet Riot Hour | Glass Field |
7 rows — all rows shown.
Constraints
first_track is the title of their earliest play by played_at; last_track is the title of their latest.u6 does, and that is correct rather than a duplicate to remove.user_id.Worked example
u2 starts with Static Bloom on 6 January and ends with Night Signal on 5 March, so the row is one line: u2, Static Bloom, Night Signal.
Write LAST_VALUE(title) OVER (PARTITION BY user_id ORDER BY played_at) with no frame clause and the query returns 22 rows instead of 7. The default frame ends at the current row, so last_track becomes the running latest — a different value on every play, and nothing for DISTINCT to collapse.
What this tests
Window frames in the form that bites hardest: under the default frame FIRST_VALUE is correct by accident and LAST_VALUE is wrong by default, so the frame has to be stated rather than assumed.
Submit for review to find out what your query gets right, what it gets wrong, and how it compares with the best working query for this exercise.
This scenario runs a full workspace — editor, canvas and results side by side. It needs a laptop or desktop to be usable. Open this page on a bigger screen to start building.