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
Licensing negotiates by genre and wants to know how the platform's total listening time splits across them. ms_played is how long the listener actually listened, which is not the same as the track's duration_ms.
Return one row per genre, ordered by share descending.
Result columns · in this order
genre | The genre. |
minutes | Minutes listened to that genre. |
pct_of_total | Its share of all listening time, as a percentage. |
How to approach it
Aggregate per genre first, then bring the total of those totals onto every row.
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
| genre | minutes | pct_of_total |
|---|---|---|
| indie | 38 | 32.2 |
| jazz | 35.5 | 30 |
| electronic | 28.9 | 24.5 |
| rock | 15.8 | 13.3 |
4 rows — all rows shown.
Constraints
minutes is the genre's ms_played divided by 60000, rounded to 1 decimal place.pct_of_total is the genre's share of all listening time, rounded to 1 decimal place. The four values add up to 100.ms_played — not the number of plays, and not duration_ms.pct_of_total descending, then genre.Worked example
jazz accumulates 2,130,000 ms — 35.5 minutes of the platform's 118.2-minute total — so pct_of_total is 30.0.
The instinct is to compute the total in a subquery that re-reads stream_plays. That works and scans the table a second time for a number the query already holds; SUM(...) OVER () takes it from the rows in front of it.
What this tests
An unpartitioned window — SUM(...) OVER () — used to place a grand total beside every grouped row, which is how a share is computed without a self-join or a second pass over the source table.
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.