计算 SQL 中的年度活跃用户
Calculating yearly active users in SQL
我有一个包含两列的 table logins
:user_id
和 login_date
。我想使用对于任何给定日期的定义来计算每个日历年的活跃用户数,如果 user_id
在过去 90 天内至少有 1 次登录,则该日期被认为是活跃的.例如,如果 user_id
有一个 2017-01-01
的 login_date
,那么这个 user_id
据说在从 2017-01-01
到 [=24= 的每一天都是活跃的].同一个 user_id
可以在 2017-02-01
上有另一个 login_date
,随后将在 2017-02-01
到 2017-05-01
的每一天都处于活动状态。使用这个定义,我想计算一下 2017 年、2018 年、2019 年和 2020 年的活跃用户数。
这是输入 table,有几个例子:
+-----------+------------+
| 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
解决这个问题的正确方法是什么?
由于您只对年度活跃用户数而不是每月活跃用户数感兴趣,因此无需确定 active_m1, active_m2, active_m3
(所有活跃月份),只需确定 active_m3
。具有 first_active_date
和 active_m3
足以确定用户是在当年还是下一年活跃。
您可以尝试以下方法:
WITH all_missions AS (
SELECT
user_id,
format_datetime(login_date, 'yyyy-MM') AS active_date
FROM
logins
UNION ALL
SELECT
user_id,
format_datetime(date_add('month', 3, login_date), 'yyyy-MM-dd') AS active_date
FROM logins
)
SELECT
YEAR(active_date) AS year_number,
count(DISTINCT user_id) AS num_active_users
FROM all_missions
GROUP BY 1
让我知道这是否适合你。
我有一个包含两列的 table logins
:user_id
和 login_date
。我想使用对于任何给定日期的定义来计算每个日历年的活跃用户数,如果 user_id
在过去 90 天内至少有 1 次登录,则该日期被认为是活跃的.例如,如果 user_id
有一个 2017-01-01
的 login_date
,那么这个 user_id
据说在从 2017-01-01
到 [=24= 的每一天都是活跃的].同一个 user_id
可以在 2017-02-01
上有另一个 login_date
,随后将在 2017-02-01
到 2017-05-01
的每一天都处于活动状态。使用这个定义,我想计算一下 2017 年、2018 年、2019 年和 2020 年的活跃用户数。
这是输入 table,有几个例子:
+-----------+------------+
| 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
解决这个问题的正确方法是什么?
由于您只对年度活跃用户数而不是每月活跃用户数感兴趣,因此无需确定 active_m1, active_m2, active_m3
(所有活跃月份),只需确定 active_m3
。具有 first_active_date
和 active_m3
足以确定用户是在当年还是下一年活跃。
您可以尝试以下方法:
WITH all_missions AS (
SELECT
user_id,
format_datetime(login_date, 'yyyy-MM') AS active_date
FROM
logins
UNION ALL
SELECT
user_id,
format_datetime(date_add('month', 3, login_date), 'yyyy-MM-dd') AS active_date
FROM logins
)
SELECT
YEAR(active_date) AS year_number,
count(DISTINCT user_id) AS num_active_users
FROM all_missions
GROUP BY 1
让我知道这是否适合你。