cswork / libraryOpen practice workspace

Coding questions · Meta

Produce dating profile funnel report by cohort

This question evaluates a data scientist's competency in cohort-based funnel analysis, metric computation (counts and rates), temporal cohorting, deduplication, and aggregation of relational event and profile data.

You work on a dating app. Produce a daily profile-funnel report for 2025-08-25 through 2025-09-01 inclusive, with one row per day, gender, and age_bucket (18–24, 25–34, 35–44, 45+). For each group, compute: profile_creation_cnt, photo_present_rate, avg_completion_rate (filled_fields/total_fields), profile_viewers_cnt (distinct viewers), likes_sent_cnt, match_rate (matches/views). Also output a separate list of user_ids with profiles missing a photo as of 2025-09-01. Assume ages are computed from birthdate at report date. Return two result sets (or two CTE outputs).

Schemas:

  • users(user_id INT, gender TEXT, birthdate DATE, country_code CHAR(2), created_at TIMESTAMP)
  • profiles(user_id INT, has_photo BOOLEAN, filled_fields INT, total_fields INT, updated_at TIMESTAMP)
  • profile_events(event_id INT, event_date DATE, actor_user_id INT, target_user_id INT, event_type TEXT CHECK (event_type IN ('view','like','match')))

Sample rows (subsets):

users
+---------+--------+------------+--------------+
| user_id | gender | birthdate | country_code |
+---------+--------+------------+--------------+
| 10 | F | 1998-05-01 | FR |
| 11 | M | 1990-02-10 | US |
| 12 | F | 1985-11-20 | US |
+---------+--------+------------+--------------+
profiles
+---------+-----------+---------------+-------------+---------------------+
| user_id | has_photo | filled_fields | total_fields| updated_at |
+---------+-----------+---------------+-------------+---------------------+
| 10 | true | 8 | 10 | 2025-08-31 10:00:00 |
| 11 | false | 5 | 10 | 2025-08-31 12:00:00 |
| 12 | true | 10 | 10 | 2025-09-01 09:00:00 |
+---------+-----------+---------------+-------------+---------------------+
profile_events
+----------+------------+---------------+---------------+------------+
| event_id | event_date | actor_user_id | target_user_id| event_type |
+----------+------------+---------------+---------------+------------+
| 9001 | 2025-08-31 | 11 | 10 | view |
| 9002 | 2025-08-31 | 11 | 10 | like |
| 9003 | 2025-08-31 | 10 | 11 | match |
+----------+------------+---------------+---------------+------------+

Clearly state any assumptions (e.g., how to bucket ages, whether match requires prior like).

Daily dating-profile funnel by signup cohort and age bucket

You work on a dating app. Using the schema below, write one PostgreSQL query that returns a single labeled result table containing both:

  1. A daily profile-funnel report for report dates from 2025-08-25 through 2025-09-01 inclusive. Treat each report_date as a signup cohort, so include only users whose created_at::date equals that report_date. Group cohort users by gender and age_bucket at the report_date, using 18-24, 25-34, 35-44, and 45+.
  2. A list of users whose latest profile as of 2025-09-01 23:59:59 has has_photo = false.

For the funnel rows, return profile_creation_cnt, photo_present_rate, avg_completion_rate, profile_viewers_cnt, likes_sent_cnt, and match_rate. Views and matches count events where the cohort user is the target on their cohort date; likes_sent_cnt counts like events sent by cohort users on their cohort date. Return all rows in one output with a result_set column. Columns that do not apply to a result_set should be NULL.

Table users

columntypeconstraints
user_idINTPRIMARY KEY
genderTEXTNOT NULL
birthdateDATENOT NULL
country_codeCHAR(2)NOT NULL
created_atTIMESTAMPNOT NULL

Sample data:

birthdatecountry_codecreated_atgenderuser_id
1998-05-01FR2025-08-25 08:00:00F10
1990-02-10US2025-08-26 09:00:00M11
1985-11-20US2025-08-20 07:30:00F12
2004-09-10US2025-08-30 10:00:00M13
1975-03-05GB2025-08-31 16:00:00F14
1999-12-12GB2025-09-01 10:00:00F16

Table profiles

columntypeconstraints
user_idINTNOT NULL
has_photoBOOLEANNOT NULL
filled_fieldsINTNOT NULL
total_fieldsINTNOT NULL
updated_atTIMESTAMPNOT NULL

Sample data:

filled_fieldshas_photototal_fieldsupdated_atuser_id
2false102025-08-25 09:00:0010
8true102025-08-31 10:00:0010
3false102025-08-26 13:00:0011
5false102025-08-31 12:00:0011
7true102025-08-20 08:00:0012
10true102025-09-01 09:00:0012
4false102025-08-30 11:00:0013
6true102025-08-31 15:00:0014
1false102025-09-01 10:30:0016

Table profile_events

columntypeconstraints
event_idINTPRIMARY KEY
event_dateDATENOT NULL
actor_user_idINTNOT NULL
target_user_idINTNOT NULL
event_typeVARCHAR(10)NOT NULL, CHECK (event_type IN ('view','like','match'))

Sample data:

actor_user_idevent_dateevent_idevent_typetarget_user_id
112025-08-319001view10
112025-08-319002like10
102025-08-319003match11
112025-08-259004view10
102025-08-269005view11
102025-08-269006like11
102025-08-269007match11
122025-08-309008view13
112025-09-019009view12
112025-09-019010like12
122025-09-019011view11
122025-09-019012match11
132025-09-019013view16
132025-09-019014like16

Expected output

Sample output for the single labeled result table.

age_bucketavg_completion_rategenderlikes_sent_cntmatch_ratephoto_present_rateprofile_creation_cntprofile_viewers_cntreport_dateresult_setuser_id
25-340.2000F00.00000.0000112025-08-25daily_profile_funnelNULL
35-440.3000M01.00000.0000112025-08-26daily_profile_funnelNULL
18-240.4000M00.00000.0000112025-08-30daily_profile_funnelNULL
45+0.6000F00.00001.0000102025-08-31daily_profile_funnelNULL
25-340.1000F00.00000.0000112025-09-01daily_profile_funnelNULL
NULLNULLNULLNULLNULLNULLNULLNULLNULLmissing_photo_users_as_of_2025_09_0111
NULLNULLNULLNULLNULLNULLNULLNULLNULLmissing_photo_users_as_of_2025_09_0113
NULLNULLNULLNULLNULLNULLNULLNULLNULLmissing_photo_users_as_of_2025_09_0116

Hints

  1. Create the report-date spine first.
  2. Use ROW_NUMBER to select the latest profile snapshot for each user/date.
  3. Return the funnel and missing-photo rows through one UNION ALL output.