Dataford
Interview Guides
Upgrade
All questions/SQL & Data Manipulation/30-Day Retention by Channel

30-Day Retention by Channel

Medium
SQL & Data Manipulation
Asked at 2 companies2JoinsAggregationsDate Functions
Also asked at
RipplingNational Veterinary Associates

Problem

Task

NovaPlay wants to measure how well each acquisition channel retains new users after signup. Write a PostgreSQL query to calculate 30-day retention by acquisition channel.

A user is considered retained if they have at least one activity event on or after signup_date + 30 days and on or before signup_date + 60 days. Use each user's acquisition channel from the acquisitions table.

Requirements

  1. Return one row per acquisition channel.
  2. For each channel, calculate:
    • total signed-up users
    • retained users
    • 30-day retention rate as a percentage rounded to 2 decimals
  3. Include users even if they have no matching acquisition row; label those as 'Unknown'.
  4. Order results by retention rate descending, then channel name ascending.

Table Definitions

users

columntypedescription
user_idINTUnique user identifier
signup_dateDATEUser signup date
countryVARCHAR(50)User country

acquisitions

columntypedescription
acquisition_idINTUnique acquisition record
user_idINTUser identifier
channelVARCHAR(50)Acquisition channel
campaign_nameVARCHAR(100)Campaign name

activity_events

columntypedescription
event_idINTUnique event identifier
user_idINTUser identifier
event_dateDATEActivity date
event_typeVARCHAR(50)Event type

Sample Data

users

user_idsignup_datecountry
42024-01-20CA
12024-01-01US
72024-02-10US
22024-01-05US
92024-02-20GB
32024-01-10GB
62024-02-01CA
82024-02-15US
52024-01-25US
102024-03-01CA

acquisitions

acquisition_iduser_idchannelcampaign_name
1011Paid SearchBrand SEM
1022Organic SearchSEO Landing
1033Paid SocialWinter Prospecting
1044ReferralInvite Program
1055Paid SearchGeneric SEM
1066EmailReactivation Blast
1077Organic SearchBlog CTA
1088Paid SocialVideo Ads
1099Unattributed Import
11011AffiliatePartner Network

activity_events

event_iduser_idevent_dateevent_type
100112024-01-15session
100212024-02-05purchase
100322024-02-04session
100422024-02-10purchase
100532024-02-08session
100642024-02-19session
100752024-03-01session
100862024-03-05purchase
100972024-03-12session
101082024-03-20session
101192024-03-25purchase
1012122024-03-10session

Expected Output

channeltotal_usersretained_usersretention_rate_pct
Email11100.00
Organic Search22100.00
Unknown2150.00
Paid Search2150.00
Paid Social200.00
Referral100.00

Schema

users
ColumnTypeDescription
user_idPKINTUnique user identifier
signup_dateDATEDate the user signed up
countryVARCHAR(50)User country
acquisitions
ColumnTypeDescription
acquisition_idPKINTUnique acquisition record identifier
user_idINTUser tied to the acquisition record
channelVARCHAR(50)Acquisition channel
campaign_nameVARCHAR(100)Marketing campaign name
activity_events
ColumnTypeDescription
event_idPKINTUnique activity event identifier
user_idINTUser who generated the event
event_dateDATEDate of the activity event
event_typeVARCHAR(50)Type of user activity

Sample Data

Example 1
Input{"users":[[4,"2024-01-20","CA"],[1,"2024-01-01","US"],[7,"2024-02-10","US"],[2,"2024-01-05","US"],[9,"2024-02-20","GB"],[3,"2024-01-10","GB"],[6,"2024-02-01","CA"],[8,"2024-02-15","US"],[5,"2024-01-25","US"],[10,"2024-03-01","CA"],["1","2024-01-08","NO"],["2","2024-01-08","null"],["3","2024-03-01","JP"],["4","2024-02-12","US"],["5","2024-01-21","AU"],["6","2024-02-04","NO"],["7","2023-12-29","null"],["8","2024-01-17","DK"],["9","2024-02-04","NL"],["10","2024-02-04","DK"],["11","2024-01-03","SE"]Output[["Content Marketing","1","1","100.00"],["Email","1","1","100.00"],["Influencer","1","1","100.00"],["Organic Search","2","2","100.00"],["Paid Search","2","2","100.00"],["Referral","1","1","100.00"],["SMS","1","1","100.00"],["Paid Social","2","1","50.00"],["Unknown","9","2","22.22"],["Affiliate","1","0","0.00"]]

Problem

Task

NovaPlay wants to measure how well each acquisition channel retains new users after signup. Write a PostgreSQL query to calculate 30-day retention by acquisition channel.

A user is considered retained if they have at least one activity event on or after signup_date + 30 days and on or before signup_date + 60 days. Use each user's acquisition channel from the acquisitions table.

Requirements

  1. Return one row per acquisition channel.
  2. For each channel, calculate:
    • total signed-up users
    • retained users
    • 30-day retention rate as a percentage rounded to 2 decimals
  3. Include users even if they have no matching acquisition row; label those as 'Unknown'.
  4. Order results by retention rate descending, then channel name ascending.

Table Definitions

users

columntypedescription
user_idINTUnique user identifier
signup_dateDATEUser signup date
countryVARCHAR(50)User country

acquisitions

columntypedescription
acquisition_idINTUnique acquisition record
user_idINTUser identifier
channelVARCHAR(50)Acquisition channel
campaign_nameVARCHAR(100)Campaign name

activity_events

columntypedescription
event_idINTUnique event identifier
user_idINTUser identifier
event_dateDATEActivity date
event_typeVARCHAR(50)Event type

Sample Data

users

user_idsignup_datecountry
42024-01-20CA
12024-01-01US
72024-02-10US
22024-01-05US
92024-02-20GB
32024-01-10GB
62024-02-01CA
82024-02-15US
52024-01-25US
102024-03-01CA

acquisitions

acquisition_iduser_idchannelcampaign_name
1011Paid SearchBrand SEM
1022Organic SearchSEO Landing
1033Paid SocialWinter Prospecting
1044ReferralInvite Program
1055Paid SearchGeneric SEM
1066EmailReactivation Blast
1077Organic SearchBlog CTA
1088Paid SocialVideo Ads
1099Unattributed Import
11011AffiliatePartner Network

activity_events

event_iduser_idevent_dateevent_type
100112024-01-15session
100212024-02-05purchase
100322024-02-04session
100422024-02-10purchase
100532024-02-08session
100642024-02-19session
100752024-03-01session
100862024-03-05purchase
100972024-03-12session
101082024-03-20session
101192024-03-25purchase
1012122024-03-10session

Expected Output

channeltotal_usersretained_usersretention_rate_pct
Email11100.00
Organic Search22100.00
Unknown2150.00
Paid Search2150.00
Paid Social200.00
Referral100.00

Schema

users
ColumnTypeDescription
user_idPKINTUnique user identifier
signup_dateDATEDate the user signed up
countryVARCHAR(50)User country
acquisitions
ColumnTypeDescription
acquisition_idPKINTUnique acquisition record identifier
user_idINTUser tied to the acquisition record
channelVARCHAR(50)Acquisition channel
campaign_nameVARCHAR(100)Marketing campaign name
activity_events
ColumnTypeDescription
event_idPKINTUnique activity event identifier
user_idINTUser who generated the event
event_dateDATEDate of the activity event
event_typeVARCHAR(50)Type of user activity

Sample Data

Example 1
Input{"users":[[4,"2024-01-20","CA"],[1,"2024-01-01","US"],[7,"2024-02-10","US"],[2,"2024-01-05","US"],[9,"2024-02-20","GB"],[3,"2024-01-10","GB"],[6,"2024-02-01","CA"],[8,"2024-02-15","US"],[5,"2024-01-25","US"],[10,"2024-03-01","CA"],["1","2024-01-08","NO"],["2","2024-01-08","null"],["3","2024-03-01","JP"],["4","2024-02-12","US"],["5","2024-01-21","AU"],["6","2024-02-04","NO"],["7","2023-12-29","null"],["8","2024-01-17","DK"],["9","2024-02-04","NL"],["10","2024-02-04","DK"],["11","2024-01-03","SE"]Output[["Content Marketing","1","1","100.00"],["Email","1","1","100.00"],["Influencer","1","1","100.00"],["Organic Search","2","2","100.00"],["Paid Search","2","2","100.00"],["Referral","1","1","100.00"],["SMS","1","1","100.00"],["Paid Social","2","1","50.00"],["Unknown","9","2","22.22"],["Affiliate","1","0","0.00"]]
Practice SQL
PostgreSQL
Open on desktop for the full SQL editor with syntax highlighting and autocomplete.
Up next
RipplingCompare Channel Retention by CohortMediumAsanaCompare Retention by Acquisition SourceMediumRipplingCalculate 30-Day User RetentionMedium
Next question