使用 T-SQL 滚动 DAU、MAU

Posted

技术标签:

【中文标题】使用 T-SQL 滚动 DAU、MAU【英文标题】:Rolling DAU, MAU using T-SQL 【发布时间】:2019-05-08 14:13:24 【问题描述】:

情况:

我有一个包含 email 和 login_time 列的登录表。我想计算每日登录时间(DAU)和滚动每月登录时间(MAU)。 DAU 和 MAU 必须计算不同的用户。即,如果某人在过去 30 天 (MAU) 中登录 20 次,那么他只会被计算一次。同样的逻辑也适用于 DAU。 MAU 的范围是 30 天。

DAU:是通过每天使用不同的电子邮件登录来计算的。

MAU: 是通过连续 30 天的不同电子邮件登录来计算的。

期望的结果: 见下面的小提琴

Date         MAU     DAU     
2019-04-01   4       2  
2019-04-02   3       2  
2019-04-03   4       2   

计算 DAU 相当简单,但是获取滚动 MAU,不知道如何。

小提琴:

create table #t1 (email varchar(max), login_time datetime)
insert into #t1 values 
('aa@gmail.com', '2019-03-15 00:00:00.000'),
('aa@gmail.com', '2019-04-01 00:00:00.000'),
('aa@gmail.com', '2019-04-02 00:00:00.000'),
('aa@gmail.com', '2019-04-03 00:00:00.000'),

('bb@gmail.com', '2019-03-19 00:00:00.000'),
('bb@gmail.com', '2019-04-01 00:00:00.000'),
('bb@gmail.com', '2019-04-02 00:00:00.000'),
('bb@gmail.com', '2019-04-02 00:00:00.000'),

('cc@gmail.com', '2019-03-02 00:00:00.000'),
('cc@gmail.com', '2019-04-03 00:00:00.000'),

('dd@gmail.com', '2019-03-06 00:00:00.000')

【问题讨论】:

你没有很好地解释 DAU 和 MAU 是如何定义的。请解释一下。 @GordonLinoff 完成。 @Cowthulhu > 2016 @Cowthulhu 非常重要,我正在处理的表每天要处理数十万次登录。 @D-Shih 不应该。在过去 30 天内是指在该 30 天范围内。此后的任何内容都不应包含在 MAU 中 【参考方案1】:

这是一种方法。

SELECT login_time, 
    m.MAU,
    COUNT(DISTINCT email) AS DAU
FROM #t1 d
CROSS APPLY (SELECT COUNT( DISTINCT email) AS MAU
            FROM #t1 m
            WHERE m.login_time BETWEEN DATEADD( dd, -30, d.login_time) AND d.login_time) m
GROUP BY login_time, m.MAU
ORDER BY login_time;

【讨论】:

【参考方案2】:

感谢 Luis,非常聪明的回答,这将是 mysql 8.X 的版本,以防万一你需要它,就像我一样:

drop table if exists t1;

create table t1 (email text, login_time datetime)
;
insert into t1 values 
('aa@gmail.com', '2019-03-15 00:00:00.000'),
('aa@gmail.com', '2019-04-01 00:00:00.000'),
('aa@gmail.com', '2019-04-02 00:00:00.000'),
('aa@gmail.com', '2019-04-03 00:00:00.000'),

('bb@gmail.com', '2019-03-19 00:00:00.000'),
('bb@gmail.com', '2019-04-01 00:00:00.000'),
('bb@gmail.com', '2019-04-02 00:00:00.000'),
('bb@gmail.com', '2019-04-02 00:00:00.000'),

('cc@gmail.com', '2019-03-02 00:00:00.000'),
('cc@gmail.com', '2019-04-03 00:00:00.000'),

('dd@gmail.com', '2019-03-06 00:00:00.000')

;
SELECT login_time, 
    m.MAU,
    COUNT(DISTINCT email) AS DAU
FROM t1 as d,
LATERAL (SELECT COUNT( DISTINCT email) AS MAU
            FROM t1 m
            WHERE m.login_time BETWEEN d.login_time - interval 30 day AND d.login_time) as m
GROUP BY login_time, m.MAU
ORDER BY login_time; 

在 MySQL 8.X 中相当于 CROSS APPLY 的是 LATERAL 关键字(意思是“这个派生表依赖于其左侧的先前表”):

【讨论】:

以上是关于使用 T-SQL 滚动 DAU、MAU的主要内容,如果未能解决你的问题,请参考以下文章

修复在 Amazon Redshift 上计算 DAU 和 MAU 时的 MAU 问题

段的 DAU/MAU 计算

查询一段时间内的 DAU/MAU(每天)

产品经理日活跃用户「MAU」 和月活跃用户「DAU」

Redshift 中的 DAU WAU MAU 错误:[Amazon](500310) 无效操作:由于内部错误,不支持此类关联子查询模式;

REDIS05_HyperLogLog的概述基本命令UVPVDAUMAU首页UV如何进行统计处理