滚动非重复计数 30 天

Rolling distinct count 30 day

我需要从 AWS Athena 转换这个事件跟踪器数据集

timestamp      id     event
1577863551     1      home
1577863555     1      profile
1577863555     2      home

从 30 天前到现在活跃的每月活跃用户或唯一用户。例如

date        MAU
2/1/2020    2000
2/2/2020    2500

2000 MAU 表示从 2020 年 1 月 3 日到 2020 年 2 月 1 日有 2000 个独立用户活跃。
2500 MAU 意味着从 1/4/2020 到 2/2/2020 有 2500 个独立用户活跃

这个比较复杂。 count(distinct) over 简单得多 !但这是个主意。

您想获取统计用户的时间段。这个想法是生成一个 user_inc,当用户开始计数时为 1,停止时为 -1

但这不好算。这个想法是为用户开始被计数和停止被计数(通过添加 31 天)添加行——这些时间段的标志为 1 和 -1`。然后累积总和确定用户在该日期是否有 activity。过滤得到句点的第一行和最后一行 activity.

所以,这看起来像:

with t as (
      select id, dte, sum(sum(inc)) over (partition by id order by dte) as running_ins
      from ((select id, date(from_unixtime(timestamp)) as dte, 1 as inc
             from event_tracker
            ) union all
            (select id, date(from_unixtime(timestamp)) + interval '31' day as dte, -1 as inc
             from event_tracker
            )
           ) id
      group by id, dte
     ),
     first_last as (
      select id, dte, (case when running_ins > 0 then 1 else -1 end) as user_inc
      from (select t.*,
                   lag(running_ins) over (partition by id order by dte) as prev_running_ins
            from t
           ) t
      where prev_running_ins is null or
            prev_running_ins = 0 and running_ins > 0 or
            prev_running_ins > 0 and running_ins = 0
     )
select fl.dte,
       sum(sum(user_inc)) over (order by fl.dte) as distinct_30_days
from first_last fl
group by fl.dte;

Here 是一个使用 Postgres 的 db<>fiddle。