cswork / libraryOpen practice workspace

Coding questions · Yahoo

Diagnose DAU drop with SQL by country

This question evaluates SQL data-manipulation and analytical skills, including DAU aggregation with per-day deduplication, date-range baseline averaging, experiment-treatment exclusion, country-level cohorting, and new vs returning user segmentation.

Write a single SQL query to diagnose a country-level DAU drop for an email product. Assume today is 2025-09-01. DAU is the count of distinct user_id with at least one of event_type IN ('login','open_mail','send_mail','push_click') on a date. Exclude is_bot = TRUE events. Also exclude users who are in experiments where exp_name = 'mail_redesign' AND exp_group = 'treatment' if the experiment is active on the date (start_date <= date <= end_date). Compare 2025-09-01 to the average DAU over the prior 7 days (2025-08-25..2025-08-31). Output the top 3 countries by absolute DAU drop with columns: country, dau_prev7d_avg, dau_today, drop_abs, drop_pct. Additionally, for each of those countries, also output dau_today_returning and dau_today_new, where returning users have created_at < '2025-08-25' and new users have created_at BETWEEN '2025-08-25' AND '2025-09-01'. Break ties in drop_abs by larger drop_pct. Use only standard SQL constructs (CTEs, window functions allowed). Schema and tiny sample data:

users

user_idcountrycreated_at
1US2025-08-10
2US2025-08-26
3IN2025-08-01
4IN2025-08-30
5US2025-07-15
6IN2025-08-27

events

event_dateuser_idevent_typedeviceapp_versionis_bot
2025-08-251loginios10.20
2025-08-311open_mailios10.20
2025-09-011open_mailios10.20
2025-08-282loginandroid10.30
2025-09-012loginandroid10.30
2025-08-273loginweb-0
2025-08-303open_mailweb-0
2025-09-013open_mailweb-0
2025-08-314loginandroid10.10
2025-09-014loginandroid10.10
2025-08-255loginios10.00
2025-08-315loginios10.00
2025-09-015loginios10.10
2025-09-016loginweb-1

experiments

user_idexp_nameexp_groupstart_dateend_date
2mail_redesigntreatment2025-08-292025-09-10
3mail_redesigncontrol2025-08-292025-09-10

Be careful to: (a) de-duplicate users per day across multiple events/devices, (b) filter experiment treatment users only for dates when the experiment is active, (c) compute the 7-day average correctly even if a country has zero DAU on some baseline days.

Diagnose Country-Level DAU Drop with Experiments and New/Returning Split

Write a single SQL query to diagnose a country-level DAU drop for an email product. Assume today is 2025-06-01.

DAU for a given date is the count of distinct user_id who have at least one event with event_type IN ('login', 'open_mail', 'send_mail', 'push_click') on that date. Exclude any events where is_bot = TRUE.

Also exclude users who are in experiments where exp_name = 'mail_redesign' AND exp_group = 'treatment' on dates when that experiment is active (start_date <= event_date AND event_date <= end_date).

Compare 2025-06-01 to the average DAU over the prior 7 days, from 2025-05-25 to 2025-05-31 (inclusive). For each country, compute:

  • dau_prev7d_avg: average DAU in the 7-day window 2025-05-25..2025-05-31
  • dau_today: DAU on 2025-06-01
  • drop_abs: dau_prev7d_avg - dau_today
  • drop_pct: drop_abs / dau_prev7d_avg (NULL if dau_prev7d_avg = 0)

Return the top 3 countries by absolute DAU drop (ORDER BY ABS(drop_abs) DESC), breaking ties by larger drop_pct (DESC).

Additionally, for each of those top-3 countries, also output:

  • dau_today_returning: count of today's DAU users with created_at < '2025-05-25'
  • dau_today_new: count of today's DAU users with created_at BETWEEN '2025-05-25' AND '2025-06-01'

Be careful to: (a) De-duplicate users per day across multiple events/devices (i.e., each user counts at most once per country per day). (b) Filter experiment treatment users only for dates when the experiment is active. (c) Compute the 7-day average correctly even if a country has zero DAU on some of the baseline days (those days should still count in the denominator of 7).

Use only standard SQL constructs (CTEs and window functions are allowed).

Table users

columntypeconstraints
user_idINTPRIMARY KEY, NOT NULL
countryVARCHAR(10)NOT NULL
created_atDATENOT NULL

Sample data:

countrycreated_atuser_id
US2025-05-101
US2025-05-262
IN2025-05-013
IN2025-05-304
US2025-04-155
IN2025-05-276

Table events

columntypeconstraints
event_dateDATENOT NULL
user_idINTNOT NULL
event_typeVARCHAR(20)NOT NULL
deviceVARCHAR(20)NOT NULL
app_versionVARCHAR(10)NOT NULL
is_botBOOLEANNOT NULL

Sample data:

app_versiondeviceevent_dateevent_typeis_botuser_id
10.2ios2025-05-25loginfalse1
10.2ios2025-05-31open_mailfalse1
10.2ios2025-06-01open_mailfalse1
10.3android2025-05-28loginfalse2
10.3android2025-06-01loginfalse2
-web2025-05-27loginfalse3
-web2025-05-30open_mailfalse3
-web2025-06-01open_mailfalse3
10.1android2025-05-31loginfalse4
10.1android2025-06-01loginfalse4
10.0ios2025-05-25loginfalse5
10.0ios2025-05-31loginfalse5
10.1ios2025-06-01loginfalse5
-web2025-06-01logintrue6

Table experiments

columntypeconstraints
user_idINTNOT NULL
exp_nameVARCHAR(50)NOT NULL
exp_groupVARCHAR(20)NOT NULL
start_dateDATENOT NULL
end_dateDATENOT NULL

Sample data:

end_dateexp_groupexp_namestart_dateuser_id
2025-06-10treatmentmail_redesign2025-05-292
2025-06-10controlmail_redesign2025-05-293

Expected output

One row per top-3 country, showing the 7-day baseline average DAU, DAU on 2025-06-01, absolute and percentage drop (baseline minus today), and the split between returning and new users for 2025-06-01.

countrydau_prev7d_avgdau_todaydau_today_newdau_today_returningdrop_absdrop_pct
IN0.429211-1.571-3.662
US0.714202-1.286-1.801

Hints

  1. First build a CTE that filters events for valid event types, removes bots, and excludes users in an active 'mail_redesign' treatment arm on that date, then de-duplicate by (event_date, user_id).
  2. Create a calendar CTE for the baseline 7 days and cross join it with the list of countries so that days with zero DAU are still included when computing the 7-day average.