ExpertAnalytics Patterns50 points

Month-1 and month-2 retention by sign-up cohort

Investors always ask: do new users stick around? Group users into cohorts by sign-up month (YYYY-MM of signup_date). A user is month-1 active if they played at least one track in the calendar month right after their sign-up month, and month-2 active for the month after that. Only include cohorts that signed up before 2026-05-01, so that both follow-up months fall inside the data.

Task: return cohort_month, cohort_size (all users of the cohort, active or not), m1_active, m2_active, and m1_pct (month-1 active users divided by cohort size times 100, ROUND(x, 2)). Sort by cohort_month. Months with zero active users still show 0.

The data you can query

Each table is shown with its column types and the first rows, so you can see exactly what the data looks like.

artists16 rows
artist_id INTEGERartist_name TEXThome_country TEXTgenre TEXT
1Tobi AdeyemiNigeriaAfrobeats
2Nala OseiGhanaAfrobeats
3Neon HanbokSouth KoreaK-Pop
4Pixel OrchidSouth KoreaK-Pop
5Luz de AlbaMexicoLatin Pop
6Rio CalienteBrazilLatin Pop

Showing the first 6 of 16 rows.

plans4 rows
plan_id INTEGERplan_name TEXTmonthly_price REAL
1Free0
2Student4.99
3Premium9.99
4Family14.99
plays365 rows
play_id INTEGERuser_id INTEGERtrack_id INTEGERplayed_at TEXTseconds_played INTEGERdevice TEXT
12152025-02-10 09:10:00174mobile
21172025-03-12 11:10:00253smart_speaker
313332025-03-25 14:26:23140desktop
413132025-03-25 14:51:34245smart_speaker
512132025-04-01 12:10:00272desktop
610132025-04-11 10:10:00272smart_tv

Showing the first 6 of 365 rows.

subscriptions51 rows
sub_id INTEGERuser_id INTEGERplan_id INTEGERstart_date TEXTend_date TEXTstatus TEXT
1132025-01-072025-09-03cancelled
2132025-11-302026-01-02cancelled
3332025-01-202025-08-23cancelled
4522025-01-28NULLactive
5642025-02-022025-03-27cancelled
6732025-02-062025-10-04cancelled

Showing the first 6 of 51 rows.

tracks48 rows
track_id INTEGERtitle TEXTartist_id INTEGERrelease_year INTEGERduration_sec INTEGER
1Midnight Lagos12019353
2Golden Highway12024156
3Paper Lanterns12022253
4Neon Rain22025249
5Velvet Satellite22026176
6Broken Harbor22020157

Showing the first 6 of 48 rows.

users60 rows
user_id INTEGERname TEXTcountry TEXTsignup_date TEXTplan_id INTEGERbirth_year INTEGER
1Aarav IyerIndia2025-01-0711998
2Diego SalazarMexico2025-01-1211982
3Lucas AlmeidaBrazil2025-01-1711976
4Oliver HartleyUnited Kingdom2025-01-2211978
5Priya BanerjeeUnited Kingdom2025-01-2721999
6Jordan WhitakerUnited States2025-02-0112006

Showing the first 6 of 60 rows.

Your query runs on SQLite. Write a single SELECT; use LIMIT instead of TOP.

Need a hint?

Turn every month into a single number (year * 12 + month) so 'next month' is simply +1, even across New Year.