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
Retention wants to know how long each listener goes quiet for. A listener can play several tracks on the same evening, and the question is about days with any listening at all — not about individual plays.
Return one row per listener who has played something, ordered by user_id.
Result columns · in this order
user_id | The listener. |
listening_days | How many distinct days they listened on. |
longest_gap_days | Their longest run of days with no listening. |
How to approach it
Reduce to one row per listener per day, then bring the previous day onto each 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.
Expected output
| user_id | listening_days | longest_gap_days |
|---|---|---|
| u1 | 3 | 29 |
| u2 | 3 | 36 |
| u3 | 4 | 35 |
| u4 | 3 | 37 |
| u5 | 3 | 24 |
| u6 | 2 | 25 |
| u8 | 1 | 0 |
7 rows — all rows shown.
Constraints
longest_gap_days is the largest number of days between two consecutive listening days for that listener, as a whole number.stream_plays only.user_id.Worked example
u3 listened on 9 and 10 January, then 14 February, then 8 March. The gaps are 1, 35 and 22 days, so listening_days is 4 and longest_gap_days is 35.
Skip the distinct-day step and u3's six raw plays produce extra gaps of 0 between two plays in the same evening. Here that noise does not change the maximum — but it makes listening_days report 6 sittings as 6 days, which is simply wrong.
What this tests
Combining LAG with a deliberate change of grain: dedupe to the unit the question is really about, then compare each row with the previous one inside its partition.
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.