使用 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 问题
Redshift 中的 DAU WAU MAU 错误:[Amazon](500310) 无效操作:由于内部错误,不支持此类关联子查询模式;