Роллинг DAU, MAU с использованием T-SQL - PullRequest
4 голосов
/ 08 мая 2019

Ситуация:

У меня есть таблица входа с колонками email и login_time.Я хотел бы рассчитать ежедневное время входа в систему (DAU) и скользящее ежемесячное время входа в систему (MAU).DAU и MAU должны считать разных пользователей.То есть, если кто-то входит в систему 20 раз за последние 30 дней (MAU), он считается только один раз.Та же логика распространяется и на DAU.Диапазон MAU составляет 30 дней.

DAU: рассчитывается с использованием отдельного адреса электронной почты в день.

MAU: рассчитывается с помощьюотдельный электронный логин для скользящих 30 дней.

Желаемый результат: см. ниже: 1018 *

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')

Ответы [ 2 ]

2 голосов
/ 08 мая 2019

Это один из способов сделать это.

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;
0 голосов
/ 23 июня 2019

Спасибо, Луис, очень умный ответ, это будет вкус 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; 

Эквивалент CROSS APPLY в MySQL 8.X - это LATERAL ключевое слово (что означает «эта производная таблица зависит от предыдущих таблиц с левой стороны»):

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...