【发布时间】:2021-11-28 19:49:08
【问题描述】:
我有一个表 logins 有两列:user_id 和 login_date。我想使用以下定义来计算每个日历年的活跃用户数,即对于任何一天,如果在过去 90 天内至少有 1 次登录,则称 user_id 在该日期处于活跃状态。例如,如果user_id 具有2017-01-01 的login_date,则称此user_id 在从2017-01-01 到2017-04-01 的每一天都处于活动状态。同一个user_id 可以在2017-02-01 上拥有另一个login_date,随后每天从2017-02-01 到2017-05-01 都处于活动状态。使用这个定义,我想计算 2017 年、2018 年、2019 年和 2020 年的活跃用户数。
这里是输入表,有几个例子:
+-----------+------------+
| user_id | login_date |
+-----------+------------+
| 0000000 | 2017-01-01 |
| 0000000 | 2017-02-01 |
| 0000001 | 2017-01-02 |
+-----------+------------+
我尝试过但认为不正确的逻辑:
对于每次登录,为用户将处于活动状态的每个月(3 个月)创建一个列:
WITH all_missions AS (
SELECT
user_id,
format_datetime(login_date, 'yyyy-MM') AS first_active_date,
format_datetime(date_add('month', 1, login_date), 'yyyy-MM-dd') AS active_m1,
format_datetime(date_add('month', 2, login_date), 'yyyy-MM-dd') AS active_m2,
format_datetime(date_add('month', 3, login_date), 'yyyy-MM-dd') AS active_m3
FROM logins
),
将列反转为行:
active_months AS (
SELECT
l.user_id,
t2.active_month,
t2.month_number
FROM logins l
CROSS JOIN unnest (
array['active_m1', 'active_m2', 'active_m3'],
array[active_m1, active_m2, active_m3]
) t2 (active_month, month_number)
),
然后只计算每个活跃月的年份并聚合来计算不同的用户数:
SELECT
substring(month_number, 1, 4) AS year_number,
count(DISTINCT user_id) AS num_active_users
FROM active_months
GROUP BY 1
解决这个问题的正确方法是什么?
【问题讨论】:
标签: sql database amazon-athena presto