cswork / libraryOpen practice workspace

Coding questions · Meta

Write SQL for initiators and French DAU%

This question evaluates SQL proficiency for time-based event analysis, covering joins, deduplication, CTEs, date/time and timezone handling, and aggregated metric calculation such as DAU and participation rates.

You are given the following PostgreSQL tables. Assume all timestamps are UTC and "today" is 2025-09-01. For any reference to "last 7 days," use the inclusive window 2025-08-26 00:00:00 to 2025-09-01 23:59:59. For any reference to "yesterday," use the date 2025-08-31.

Schema:

  • users(user_id bigint primary key, country text)
  • sessions(event_date date, user_id bigint) -- one or more rows per user per day are possible
  • calls(call_id bigint primary key, initiator_id bigint, started_at timestamp, is_group_call boolean)
  • call_participants(call_id bigint, user_id bigint) -- includes the initiator and all other participants

Small sample data:

users
+---------+---------+
| user_id | country |
+---------+---------+
| 1 | FR |
| 2 | FR |
| 3 | US |
| 4 | FR |
| 5 | IN |
sessions
+------------+---------+
| event_date | user_id |
+------------+---------+
| 2025-08-31 | 1 |
| 2025-08-31 | 2 |
| 2025-08-31 | 3 |
| 2025-09-01 | 1 |
| 2025-09-01 | 4 |
calls
+----------+--------------+---------------------+---------------+
| call_id | initiator_id | started_at | is_group_call |
+----------+--------------+---------------------+---------------+
| 10 | 1 | 2025-08-26 09:00:00 | false |
| 11 | 2 | 2025-08-31 21:00:00 | true |
| 12 | 3 | 2025-09-01 01:00:00 | false |
| 13 | 1 | 2025-08-20 12:00:00 | true |
| 14 | 4 | 2025-08-31 23:30:00 | true |
call_participants
+----------+---------+
| call_id | user_id |
+----------+---------+
| 10 | 1 |
| 10 | 3 |
| 11 | 2 |
| 11 | 4 |
| 11 | 5 |
| 12 | 3 |
| 12 | 1 |
| 14 | 2 |
| 14 | 4 |

Tasks: Q1. Return the distinct users who initiated at least one video call (group or 1:1) in the last 7 days (2025-08-26 00:00:00 to 2025-09-01 23:59:59, inclusive). Output columns: user_id. Q2. Compute the percentage of daily active users from France who were on a video call yesterday (2025-08-31). Denominator: distinct users with a sessions.event_date = '2025-08-31' and users.country = 'FR'. Numerator: among those French users, the distinct users who appear in call_participants for calls whose DATE(started_at) = '2025-08-31'. Output columns: ref_date (date), dau_france (int), on_call_france (int), pct_on_call_france (numeric, percentage rounded to 2 decimals). Treat multiple sessions per user correctly (dedupe), and include users who both initiated and participated only once in the numerator. Write a single SQL script with CTEs that answers both Q1 and Q2, and clearly states any timezone/local-date assumptions.

Distinct Initiators in the Last 7 Days

You are given the following PostgreSQL tables. Assume all timestamps are stored in UTC. Treat "today" as 2025-06-01. For any reference to "last 7 days," use the inclusive window from 2025-05-26 00:00:00 to 2025-06-01 23:59:59 (UTC).

Schema:

  • users(user_id bigint primary key, country text)
  • sessions(event_date date, user_id bigint) -- one or more rows per user per day are possible
  • calls(call_id bigint primary key, initiator_id bigint, started_at timestamp, is_group_call boolean)
  • call_participants(call_id bigint, user_id bigint) -- includes the initiator and all other participants

Task (Q1): Return the distinct users who initiated at least one video call (group or 1:1) in the last 7 days, i.e., with calls.started_at between '2025-05-26 00:00:00' and '2025-06-01 23:59:59' inclusive, using UTC timestamps. Output columns: user_id.

Table users

columntypeconstraints
user_idBIGINTPRIMARY KEY
countryVARCHAR(2)NOT NULL

Sample data:

countryuser_id
FR1
FR2
US3
FR4
IN5

Table sessions

columntypeconstraints
event_dateDATENOT NULL
user_idBIGINTNOT NULL

Sample data:

event_dateuser_id
2025-05-311
2025-05-312
2025-05-313
2025-06-011
2025-06-014

Table calls

columntypeconstraints
call_idBIGINTPRIMARY KEY
initiator_idBIGINTNOT NULL
started_atTIMESTAMPNOT NULL
is_group_callBOOLEANNOT NULL

Sample data:

call_idinitiator_idis_group_callstarted_at
101false2025-05-26 09:00:00
112true2025-05-31 21:00:00
123false2025-06-01 01:00:00
131true2025-05-20 12:00:00
144true2025-05-31 23:30:00

Table call_participants

columntypeconstraints
call_idBIGINTNOT NULL
user_idBIGINTNOT NULL

Sample data:

call_iduser_id
101
103
112
114
115
123
121
142
144

Expected output

One row per distinct user_id who initiated at least one call with started_at between 2025-05-26 00:00:00 and 2025-06-01 23:59:59 UTC. Based on the sample data, calls 10, 11, 12, and 14 are in this window, so initiators 1, 2, 3, and 4 should be returned.

user_id
1
2
3
4

Hints

  1. Filter calls by the started_at timestamp window using BETWEEN.
  2. Use DISTINCT on initiator_id to get each user only once.

French DAU on Calls (Percentage for a Given Day)

Using the same PostgreSQL schema as in Question 1, assume all timestamps are stored in UTC and DATE(started_at) is computed in UTC. Treat "yesterday" as the calendar date 2025-05-31.

Schema:

  • users(user_id bigint primary key, country text)
  • sessions(event_date date, user_id bigint) -- one or more rows per user per day are possible
  • calls(call_id bigint primary key, initiator_id bigint, started_at timestamp, is_group_call boolean)
  • call_participants(call_id bigint, user_id bigint) -- includes the initiator and all other participants

Task (Q2): Compute the percentage of daily active users from France who were on a video call on 2025-05-31.

  • Denominator (dau_france): distinct users such that sessions.event_date = '2025-05-31' AND users.country = 'FR'. Handle multiple sessions per user by deduplicating.
  • Numerator (on_call_france): among those French DAU users, the distinct users who appear in call_participants for calls whose DATE(started_at) = '2025-05-31' (UTC day). Include users regardless of whether they initiated or just participated in the call.
  • pct_on_call_france: the percentage (on_call_france / dau_france * 100), rounded to 2 decimal places.

Output columns: ref_date (date), dau_france (int), on_call_france (int), pct_on_call_france (numeric, percentage). The result should contain a single row for 2025-05-31. Write a SQL query that uses CTEs to structure the computation.

Table users

columntypeconstraints
user_idBIGINTPRIMARY KEY
countryVARCHAR(2)NOT NULL

Sample data:

countryuser_id
FR1
FR2
US3
FR4
IN5

Table sessions

columntypeconstraints
event_dateDATENOT NULL
user_idBIGINTNOT NULL

Sample data:

event_dateuser_id
2025-05-311
2025-05-312
2025-05-313
2025-06-011
2025-06-014

Table calls

columntypeconstraints
call_idBIGINTPRIMARY KEY
initiator_idBIGINTNOT NULL
started_atTIMESTAMPNOT NULL
is_group_callBOOLEANNOT NULL

Sample data:

call_idinitiator_idis_group_callstarted_at
101false2025-05-26 09:00:00
112true2025-05-31 21:00:00
123false2025-06-01 01:00:00
131true2025-05-20 12:00:00
144true2025-05-31 23:30:00

Table call_participants

columntypeconstraints
call_idBIGINTNOT NULL
user_idBIGINTNOT NULL

Sample data:

call_iduser_id
101
103
112
114
115
123
121
142
144

Expected output

A single row summarizing, for 2025-05-31, how many French users were active (had at least one session) and how many of those were on at least one call that day, plus the percentage. From the sample data: French DAU users on 2025-05-31 are user 1 and 2 (dau_france = 2). Calls on 2025-05-31 are call_id 11 and 14. French DAU users participating in these calls: only user 2 (on_call_france = 1). The percentage is 1/2 * 100 = 50.00.

dau_franceon_call_francepct_on_call_franceref_date
21502025-05-31

Hints

  1. First identify French DAU for 2025-05-31 by joining sessions and users and selecting DISTINCT user_id.
  2. Then find which of those DAU users appear in call_participants for calls whose DATE(started_at) is 2025-05-31, and compute the percentage.