lesson 58 Advanced product analysis · advanced
Experiment conversion denominators
Choose the correct population for experiment conversion rates.
the idea
An experiment’s conversion rate divides converters by everyone assigned to the variant, not by users who happened to be active afterwards. A conversion counts only if it happens at or after the user’s assignment and before the measurement window ends.
Dataset: Product / SaaS Analytics
The tables the challenges use, with their first 6 rows. Under each column name: the kind of value it holds, and which table it links to.
events8 columns · 135,428 rows
| delivery_idnumber · unique id | event_idtext | user_idnumber · links to users | account_idnumber · links to accounts | session_idnumber · links to sessions | event_nametext | occurred_atdate & time | received_atdate & time |
|---|---|---|---|---|---|---|---|
| 1 | evt_0000001 | 1 | 1 | 1 | user_signed_up | 2024-01-14 18:52:14 | 2024-01-14 18:52:33 |
| 2 | evt_0000002 | 1 | 1 | 1 | onboarding_started | 2024-01-14 18:52:51 | 2024-01-14 18:53:06 |
| 3 | evt_0000084 | 6 | 2 | 32 | user_signed_up | 2024-01-15 13:21:52 | 2024-01-15 13:22:00 |
| 4 | evt_0000085 | 6 | 2 | 32 | onboarding_started | 2024-01-15 13:22:05 | 2024-01-15 13:22:16 |
| 5 | evt_0000086 | 6 | 2 | 32 | onboarding_completed | 2024-01-15 13:23:52 | 2024-01-15 13:24:12 |
| 6 | evt_0000019 | 1 | 1 | 9 | search_performed | 2024-01-17 20:56:55 | 2024-01-17 20:56:59 |
- delivery_idnumber · unique id
- 1
- event_idtext
- evt_0000001
- user_idnumber · links to users
- 1
- account_idnumber · links to accounts
- 1
- session_idnumber · links to sessions
- 1
- event_nametext
- user_signed_up
- occurred_atdate & time
- 2024-01-14 18:52:14
- received_atdate & time
- 2024-01-14 18:52:33
- delivery_idnumber · unique id
- 2
- event_idtext
- evt_0000002
- user_idnumber · links to users
- 1
- account_idnumber · links to accounts
- 1
- session_idnumber · links to sessions
- 1
- event_nametext
- onboarding_started
- occurred_atdate & time
- 2024-01-14 18:52:51
- received_atdate & time
- 2024-01-14 18:53:06
- delivery_idnumber · unique id
- 3
- event_idtext
- evt_0000084
- user_idnumber · links to users
- 6
- account_idnumber · links to accounts
- 2
- session_idnumber · links to sessions
- 32
- event_nametext
- user_signed_up
- occurred_atdate & time
- 2024-01-15 13:21:52
- received_atdate & time
- 2024-01-15 13:22:00
- delivery_idnumber · unique id
- 4
- event_idtext
- evt_0000085
- user_idnumber · links to users
- 6
- account_idnumber · links to accounts
- 2
- session_idnumber · links to sessions
- 32
- event_nametext
- onboarding_started
- occurred_atdate & time
- 2024-01-15 13:22:05
- received_atdate & time
- 2024-01-15 13:22:16
- delivery_idnumber · unique id
- 5
- event_idtext
- evt_0000086
- user_idnumber · links to users
- 6
- account_idnumber · links to accounts
- 2
- session_idnumber · links to sessions
- 32
- event_nametext
- onboarding_completed
- occurred_atdate & time
- 2024-01-15 13:23:52
- received_atdate & time
- 2024-01-15 13:24:12
- delivery_idnumber · unique id
- 6
- event_idtext
- evt_0000019
- user_idnumber · links to users
- 1
- account_idnumber · links to accounts
- 1
- session_idnumber · links to sessions
- 9
- event_nametext
- search_performed
- occurred_atdate & time
- 2024-01-17 20:56:55
- received_atdate & time
- 2024-01-17 20:56:59
first 6 of 135,428 rows · your queries use all of them
experiment_assignments4 columns · 14,939 rows
| experiment_idnumber · links to experiments | user_idnumber · links to users | varianttext | assigned_atdate & time |
|---|---|---|---|
| 1 | 1 | control | 2024-02-23 16:30:17 |
| 1 | 2 | treatment | 2024-02-06 23:25:21 |
| 1 | 3 | treatment | 2024-02-12 18:16:57 |
| 1 | 5 | treatment | 2024-02-12 02:53:31 |
| 1 | 11 | treatment | 2024-02-17 02:35:18 |
| 1 | 13 | control | 2024-02-11 14:48:37 |
- experiment_idnumber · links to experiments
- 1
- user_idnumber · links to users
- 1
- varianttext
- control
- assigned_atdate & time
- 2024-02-23 16:30:17
- experiment_idnumber · links to experiments
- 1
- user_idnumber · links to users
- 2
- varianttext
- treatment
- assigned_atdate & time
- 2024-02-06 23:25:21
- experiment_idnumber · links to experiments
- 1
- user_idnumber · links to users
- 3
- varianttext
- treatment
- assigned_atdate & time
- 2024-02-12 18:16:57
- experiment_idnumber · links to experiments
- 1
- user_idnumber · links to users
- 5
- varianttext
- treatment
- assigned_atdate & time
- 2024-02-12 02:53:31
- experiment_idnumber · links to experiments
- 1
- user_idnumber · links to users
- 11
- varianttext
- treatment
- assigned_atdate & time
- 2024-02-17 02:35:18
- experiment_idnumber · links to experiments
- 1
- user_idnumber · links to users
- 13
- varianttext
- control
- assigned_atdate & time
- 2024-02-11 14:48:37
first 6 of 14,939 rows · your queries use all of them
worked example
Run these steps in order to see the idea before you write your own query. The step marked “the pattern” is what the challenges ask for. Running the example does not count toward progress.
Count users per variant. Run this. assigned is everyone split into A or B for experiment 6—the denominator for conversion rate.the pattern
example.sqlSELECT x.experiment_key, a.variant, COUNT(*) AS assigned FROM experiment_assignments a JOIN experiments x USING (experiment_id) WHERE x.experiment_id = 6 GROUP BY x.experiment_key, a.variant;
See a biased denominator. Run this. Inner-joining conversions drops users who never created a report, so both variants look almost 100% converted.
step-2.sqlSELECT a.variant, COUNT(DISTINCT a.user_id) AS users_seen FROM experiment_assignments a JOIN events e ON e.user_id = a.user_id AND e.event_name = 'report_created' AND e.occurred_at >= a.assigned_at WHERE a.experiment_id = 6 GROUP BY a.variant;
common mistake
Inner-joining assignments to conversion events drops assigned users who never converted, so both variants look close to 100%.