【问题标题】:Calculating yearly active users in SQL用 SQL 计算年活跃用户数
【发布时间】:2021-11-28 19:49:08
【问题描述】:

我有一个表 logins 有两列:user_idlogin_date。我想使用以下定义来计算每个日历年的活跃用户数,即对于任何一天,如果在过去 90 天内至少有 1 次登录,则称 user_id 在该日期处于活跃状态。例如,如果user_id 具有2017-01-01login_date,则称此user_id 在从2017-01-012017-04-01 的每一天都处于活动状态。同一个user_id 可以在2017-02-01 上拥有另一个login_date,随后每天从2017-02-012017-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


    【解决方案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
    

    让我知道这是否适合你。

    【讨论】:

      猜你喜欢
      • 2015-02-25
      • 1970-01-01
      • 2021-10-26
      • 2020-10-06
      • 1970-01-01
      • 2012-05-24
      • 1970-01-01
      • 2020-07-06
      • 1970-01-01
      相关资源
      最近更新 更多