计算 SQL 中的年度活跃用户

Calculating yearly active users in SQL

我有一个包含两列的 table loginsuser_idlogin_date。我想使用对于任何给定日期的定义来计算每个日历年的活跃用户数,如果 user_id 在过去 90 天内至少有 1 次登录,则该日期被认为是活跃的.例如,如果 user_id 有一个 2017-01-01login_date,那么这个 user_id 据说在从 2017-01-01 到 [=24= 的每一天都是活跃的].同一个 user_id 可以在 2017-02-01 上有另一个 login_date,随后将在 2017-02-012017-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_dateactive_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

让我知道这是否适合你。