You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不通过GROUP BY聚合丢行计算DAU及滚动30天MAU

保留明细行的滚动30天去重MAU实现方案

绝大多数SQL引擎的count(distinct)窗口函数仅支持分区级全量计算,不支持搭配自定义滑动窗口范围(rows/range between)做去重计数,这也是你能直接用窗口函数算出单日DAU,但无法用同款逻辑实现滚动30天MAU的根本原因。
下面给两种可落地的实现方式:

方案1:聚合回表关联(全引擎兼容,数值100%准确)

这个方案复用你已经验证过正确的聚合计算逻辑,先在日期粒度算出准确的DAU、滚动MAU,再关联回原始明细表,既保留所有明细字段,计算结果也和你之前的聚合输出完全一致。

with daily_metric as (
    -- 这部分完全复用你已验证正确的DAU/MAU计算逻辑
    with dau as (
        select 
            to_date("EventTime") as event_date, 
            count(distinct "UserKey") as dau
        from table
        group by event_date
    )
    select 
        event_date,
        dau,
        (
            select count(distinct "UserKey") 
            from table
            where to_date("EventTime") between dateadd(day, -29, dau.event_date) and dau.event_date
        ) as mau
    from dau
)
-- 关联回原始明细表,保留全部明细行
select 
    origin.*,
    to_date(origin."EventTime") as event_date,
    metric.dau,
    metric.mau
from table origin
left join daily_metric metric
on to_date(origin."EventTime") = metric.event_date;

这个方案的优势:

  • 计算逻辑经过验证,不会出现去重计数错误
  • 无语法依赖,MySQL、Hive、Spark、ClickHouse、Presto等所有支持SQL的引擎都可以运行
  • 性能远高于直接在明细层做滑动窗口去重:聚合计算仅在日期粒度执行1次,不需要对全量明细行重复做30天范围的用户去重

方案2:原生滑动窗口写法(仅部分新版引擎支持)

如果你使用的是Spark 3.1+、BigQuery、Snowflake等新版数仓引擎,且引擎支持count(distinct)搭配滑动窗口语法,可以直接在明细层计算,不需要额外关联:

select 
    *,
    to_date("EventTime") as event_date,
    count(distinct "UserKey") over (partition by to_date("EventTime")) as dau,
    count(distinct "UserKey") over (
        order by to_date("EventTime")
        range between interval 29 day preceding and current row
    ) as mau
from table;

注意:使用前请先用小批量数据验证语法兼容性,大部分旧版本引擎运行这段代码会报语法错误。如果业务允许1%以内的计数误差,可以把count(distinct)替换为引擎自带的近似去重函数(比如approx_count_distinct、uniq、HLL_COUNT.MERGE),计算性能会有数量级提升。

内容的提问来源于stack exchange,提问作者Fizza Kashif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 19:09:23