【问题标题】:SQL Count distinct per 30 days每 30 天不同的 SQL 计数
【发布时间】:2020-02-11 07:36:03
【问题描述】:

SQL 是否可以向后每 30 天或 MAU(每月活跃用户)计数?例如,如果我有这样的数据:

date          user
1/1/2020      A
1/2/2020      B
1/2/2020      C
...
1/30/2020     Z

我使用 DISTINCT COUNT 将其转换为这样的

date          distinct_user
1/1/2020      1
1/2/2020      2
...
1/30/2020     30

为了方便起见,假设不同用户是每天活跃的不同用户的数量,并且天之间没有重叠(实际上存在重叠)。所以MAU的结果会是这样的

date          distinct_user     MAU
1/1/2020      1                 1
1/2/2020      2                 3
...
1/30/2020     30                465

465 是计算 30 天内不同用户的结果(假设每天没有重叠用户)。所以如果在 2020 年 1 月 31 日有 5 个新用户活跃,结果将是这样的

date          distinct_user     MAU
1/1/2020      1                 1
1/2/2020      2                 3
...
1/30/2020     30                465
1/31/2020     5                 469

469 来自 (Last MAU) + (new distinct user) - (distinct user from 1/1/2020, because the range is 30 days) 所以结果是 465 + 5 - 1 假设有 5 个活跃用户于 2020 年 1 月 31 日在 2020 年 1 月 2 日至 2020 年 1 月 30 日期间无效

【问题讨论】:

  • 我看到的问题是您没有关于在特定日期访问该站点的用户的信息。您怎么知道 1 月 30 日访问您的用户与 31 日访问的用户不同?如果您有此信息,则查询只是一个微不足道的 SELECT COUNT (DISTINTICT user_id) FROM ....
  • 糟糕,我会编辑我的帖子

标签: sql group-by amazon-athena amazon-quicksight


【解决方案1】:

有不同的方法可以回答这个问题,就性能而言,更好的方法可能如下:

SELECT mt1.`date`, SUM(mt2.distinct_user) AS MAU
FROM (
    SELECT `date`
    FROM myTable
    GROUP BY `date`
) mt1 INNER JOIN (
    SELECT `date`, SUM(distinct_user) AS distinct_user
    FROM myTable
    GROUP BY `date`
) mt2
WHERE mt2.`date` BETWEEN mt1.`date` - INTERVAL 29 DAY AND mt1.`date` 
GROUP BY mt1.`date`
ORDER BY mt1.`date`;

SEE DEMO HERE

【讨论】:

    【解决方案2】:

    也许最简单的方法是“反透视”数据并重新聚合:

    with t1 as (
          select date, user, 1 as inc
          from t
          union all
          select date + interval 30 day, user, -1 as inc
          from t
         ),
    select date,
           sum(case when sum_inc > 0 then 1 else 0 end) as running_30day_users
    from (select t1.*,
                 sum(inc) over (partition by user order by date) as sum_inc
          from t1
         ) t1
    group by date;
    

    我应该注意到,这也可以用 SQL 表示为:

    select distinct date, running_30
    from (select t.*,
                 count(distinct user) over (order by date range between interval 29 day preceding and current date) as running_30
          from t
         ) t;
    

    但是,我不确定 Athena 是否支持该语法。

    【讨论】:

      猜你喜欢
      • 2021-08-25
      • 1970-01-01
      • 1970-01-01
      • 2020-11-30
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      • 2019-02-17
      相关资源
      最近更新 更多