
题目
我们有两个表,一个是 notification_deliveries 表,另一个是包含 created 和购买 conversion dates 的 users 表。如果用户没有购买,那么 conversion_date 列为 NULL。
编写一个查询,以获取用户转换前的推送通知总数的分布情况。
示例:
输入:
notification_deliveries 表
| 列名 | 类型 |
|---|---|
notification | VARCHAR |
user_id | INTEGER |
created_at | DATETIME |
users 表
| 列名 | 类型 |
|---|---|
id | INTEGER |
created_at | DATETIME |
conversion_date | DATETIME |
输出:
| 列名 | 类型 |
|---|---|
total_pushes | INTEGER |
frequency | INTEGER |
答案
解题思路
如果查看用户转换前收到的推送通知总数的分布情况,最终的结果应该看起来像下面这样:
total_pushes | frequency
-------------+----------0 | 1001 | 2502 | 300... | ...
购买前收到消息次数为0的用户人数有100个, 购买前接受了1次消息的有250人,接收了2次消息的用户有300人……
我们需要获取用户转换前推送通知的总数分布,可以考虑以下几点:
- 在两个表之间根据
user_id字段进行连接。 - 排除所有未转换的用户。
- 将
conversion_date设置为大于notification_deliveries表中的created_at值,以获取发送给用户的所有通知。
我们知道这是一个 LEFT JOIN,以确保包含那些在没有任何推送通知的情况下转换的用户。
我们可以先计算每个用户的通知数量,然后按该数量分组,以获取总体分布。
答案代码
下面是实现该需求的SQL查询:
SELECT total_pushes, COUNT(*) AS frequency
FROM (SELECT u.id, COUNT(nd.notification) as total_pushesFROM users AS uLEFT JOIN notification_deliveries AS ndON u.id = nd.user_idAND u.conversion_date >= nd.created_atWHERE u.conversion_date IS NOT NULLGROUP BY 1
) AS pushes
GROUP BY 1
LEFT JOIN: 确保即使用户没有收到任何推送通知也能被包含在内。u.conversion_date >= nd.created_at: 确保只计算在用户转换之前发送的通知。COUNT(nd.notification): 计算每个用户在转换前收到的通知数量。GROUP BY: 对每个用户计算的通知数量进行分组,然后对这些分组进行频率统计。
通过以上查询,可以得到每个用户在转换前收到的推送通知总数的分布情况。
更多详细答案可关注公众号查阅。
