๐ Problem Description:
You are given two tables:
Signups
: Contains sign-up information for each user.Confirmations
: Contains requests for confirmation messages by users, with the status of each request.
Your task is to calculate the confirmation rate for each user โ i.e., the percentage of confirmation messages that were successfully confirmed.
๐งพ Table Schemas:
๐ Signups
Table:
sql
+-----------+---------------------+
| user_id | time_stamp |
+-----------+---------------------+
| int | datetime |
+-----------+---------------------+
user_id
is the primary key.- Each row represents when a user signed up.
๐จ Confirmations
Table:
sql
+-----------+---------------------+-----------+
| user_id | time_stamp | action |
+-----------+---------------------+-----------+
| int | datetime | ENUM |
+-----------+---------------------+-----------+
(user_id, time_stamp)
is the primary key.user_id
references Signups.user_id
.action
is either 'confirmed'
or 'timeout'
.
๐ง Objective:
Calculate the confirmation rate per user:
- Defined as
confirmed_count / total_count
- Round to 2 decimal places
- If a user has no confirmation records, the rate is 0.00
๐งช Example Input:
Signups
Table:
sql
+---------+---------------------+
| user_id | time_stamp |
+---------+---------------------+
| 3 | 2020-03-21 10:16:13 |
| 7 | 2020-01-04 13:57:59 |
| 2 | 2020-07-29 23:09:44 |
| 6 | 2020-12-09 10:39:37 |
+---------+---------------------+
Confirmations
Table:
sql
+---------+---------------------+-----------+
| user_id | time_stamp | action |
+---------+---------------------+-----------+
| 3 | 2021-01-06 03:30:46 | timeout |
| 3 | 2021-07-14 14:00:00 | timeout |
| 7 | 2021-06-12 11:57:29 | confirmed |
| 7 | 2021-06-13 12:58:28 | confirmed |
| 7 | 2021-06-14 13:59:27 | confirmed |
| 2 | 2021-01-22 00:00:00 | confirmed |
| 2 | 2021-02-28 23:59:59 | timeout |
+---------+---------------------+-----------+
โ
Expected Output:
sql
+---------+-------------------+
| user_id | confirmation_rate |
+---------+-------------------+
| 6 | 0.00 |
| 3 | 0.00 |
| 7 | 1.00 |
| 2 | 0.50 |
+---------+-------------------+
๐งพ SQL Solution:
sql
SELECT
s.user_id,
ROUND(
IFNULL(SUM(c.action = 'confirmed') / COUNT(c.action), 0),
2
) AS confirmation_rate
FROM Signups s
LEFT JOIN Confirmations c
ON s.user_id = c.user_id
GROUP BY s.user_id;
๐ Explanation:
LEFT JOIN
ensures all users from Signups
are included (even those with no confirmations).SUM(c.action = 'confirmed')
counts confirmed actions (returns 1 for 'confirmed', 0 otherwise).COUNT(c.action)
counts all confirmation actions (both confirmed and timeout).IFNULL(..., 0)
ensures that if there were no confirmation records, the result is 0.ROUND(..., 2)
ensures the confirmation rate is rounded to 2 decimal places.
๐ก Alternate Solution (Using CASE):
sql
SELECT
s.user_id,
ROUND(
IFNULL(SUM(CASE WHEN c.action = 'confirmed' THEN 1 ELSE 0 END)
/ COUNT(c.action), 0),
2
) AS confirmation_rate
FROM Signups s
LEFT JOIN Confirmations c
ON s.user_id = c.user_id
GROUP BY s.user_id;
This version does the same thing but uses a CASE WHEN
clause for more clarity.