情况:
我有一个登录表,其中包含列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')
答案 0 :(得分: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;
答案 1 :(得分:0)
感谢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;
关键字LATERAL(在MySQL 8.X中相当于CROSS APPLY)(表示“此派生表取决于左侧的先前表”)