MySQL-根据数周的登录历史记录获取用户数

时间:2019-03-31 15:51:27

标签: mysql mysqli

有两个表-userslogin_history

----------------------------------------------
-- user_id -- | -- created -------------------
--  1  ------ | -- 2018-11-01 13:07:24 -------
--  2  ------ | -- 2018-12-01 13:08:24 -------
--  3  ------ | -- 2019-01-01 13:09:24 -------
--  4  ------ | -- 2019-02-01 13:10:24 -------
--  5  ------ | -- 2019-02-01 13:11:24 -------
----------------------------------------------

以下查询根据创建时的YEARMONTH返回上述用户的数量。

SELECT MONTH(created) as monthly, YEAR(created) as yearly, 
       count(*) as new_users FROM users
GROUP BY YEAR(created),MONTH(created)
ORDER BY YEAR(created) DESC, MONTH(created) DESC

返回以下数据,该数据显示每个在1月,2018年12月,2019年1月创建的用户和2个在2019年2月创建的用户:

------------------------------------
----monthly---yearly----new_users---
----11--------2018-------1----------
----12--------2018-------1----------
----1---------2019-------1----------
----2---------2019-------2----------
------------------------------------

另一个表login_history保留系统中用户登录的记录,该记录显示具有user_id的用户在2018年11月登录了5次,在2018年12月,2019年1月和2月分别登录了2次2019年:

----------------------------------------------
-- user_id -- | -- login_time ----------------
--  1  ------ | -- 2018-11-01 13:07:24 -------
--  1  ------ | -- 2018-11-02 13:07:24 -------
--  1  ------ | -- 2018-11-09 13:07:24 -------
--  1  ------ | -- 2018-11-10 13:07:24 -------
--  1  ------ | -- 2018-11-21 13:07:24 -------
--  1  ------ | -- 2018-12-01 13:07:24 -------
--  1  ------ | -- 2018-12-11 13:07:24 -------
--  1  ------ | -- 2019-01-01 13:07:24 -------
--  1  ------ | -- 2018-01-05 13:07:24 -------
--  1  ------ | -- 2018-02-01 13:07:24 -------
--  1  ------ | -- 2018-02-07 13:07:24 -------
----------------------------------------------

现在,基于相似的数据集,我必须获取在一年中的特定月份创建的用户的数量,这些用户在第一周,第二周,第三周等等再次登录系统。 ....直到第5周。

我已将样本数据集更改为更大,并且输出应如下所示,例如,在2018年11月创建了100个新用户,第1周登录了100个用户中的98个,第2周登录了100个用户中的80个,依此类推...

------------------------------------------------------------------------------------------
----monthly---yearly----new_users-------week1------week2----week3------week4-----week5----
----11--------2018-------100-------------98---------80-------60---------70--------10------
----12--------2018-------200-------------190--------150------120--------100-------30------
----1---------2019-------300-------------288--------250------200--------100-------50------
----2---------2019-------400-------------360--------200-------100--------50-------5-------
------------------------------------------------------------------------------------------

到目前为止,我已经尝试过以下操作,但是我无法获得周数:

SELECT t1.monthly, t1.yearly, t1.total as total_users, t2.total as logins from (
SELECT user_id, count(*) as total, YEAR(created) as yearly, MONTH(created) as monthly FROM users
GROUP BY user_id, YEAR(created),MONTH(created)
ORDER BY YEAR(created) DESC, MONTH(created) DESC) t1
join (SELECT user_id, COUNT(*) as total from login_history
GROUP BY user_id) t2
ON t1.user_id = t2.user_id;

1 个答案:

答案 0 :(得分:0)

下面的查询返回一个数据集,该数据集显示随后几周内有多少用户登录。

SELECT
 MONTH(u.created) as monthly, YEAR(u.created) as yearly, count(DISTINCT u.user_id) as new_users,
 COUNT(DISTINCT CASE WHEN lh.login_time BETWEEN u.created AND (u.created + INTERVAL 1 WEEK) THEN  u.user_id END) AS week1,
 COUNT(DISTINCT CASE WHEN lh.login_time BETWEEN DATE_ADD(u.created, INTERVAL 1 WEEK) AND ( DATE_ADD(u.created, INTERVAL 1 WEEK) + INTERVAL 1 WEEK) THEN u.user_id END) AS week2,
 COUNT(DISTINCT CASE WHEN lh.login_time BETWEEN DATE_ADD(u.created, INTERVAL 2 WEEK) AND ( DATE_ADD(u.created, INTERVAL 2 WEEK) + INTERVAL 1 WEEK) THEN u.user_id END) AS week3,
 COUNT(DISTINCT CASE WHEN lh.login_time BETWEEN DATE_ADD(u.created, INTERVAL 3 WEEK) AND ( DATE_ADD(u.created, INTERVAL 3 WEEK) + INTERVAL 1 WEEK) THEN u.user_id END) AS week4,
 COUNT(DISTINCT CASE WHEN lh.login_time BETWEEN DATE_ADD(u.created, INTERVAL 4 WEEK) AND ( DATE_ADD(u.created, INTERVAL 4 WEEK) + INTERVAL 1 WEEK) THEN u.user_id END) AS week5,
 COUNT(DISTINCT CASE WHEN lh.login_time BETWEEN DATE_ADD(u.created, INTERVAL 5 WEEK) AND ( DATE_ADD(u.created, INTERVAL 5 WEEK) + INTERVAL 1 WEEK) THEN u.user_id END) AS week6,
 COUNT(DISTINCT CASE WHEN lh.login_time BETWEEN DATE_ADD(u.created, INTERVAL 6 WEEK) AND ( DATE_ADD(u.created, INTERVAL 6 WEEK) + INTERVAL 1 WEEK) THEN u.user_id END) AS week7,
 COUNT(DISTINCT CASE WHEN lh.login_time BETWEEN DATE_ADD(u.created, INTERVAL 7 WEEK) AND ( DATE_ADD(u.created, INTERVAL 7 WEEK) + INTERVAL 1 WEEK) THEN u.user_id END) AS week8,
 COUNT(DISTINCT CASE WHEN lh.login_time BETWEEN DATE_ADD(u.created, INTERVAL 8 WEEK) AND ( DATE_ADD(u.created, INTERVAL 8 WEEK) + INTERVAL 1 WEEK) THEN u.user_id END) AS week9,
 COUNT(DISTINCT CASE WHEN lh.login_time BETWEEN DATE_ADD(u.created, INTERVAL 9 WEEK) AND ( DATE_ADD(u.created, INTERVAL 9 WEEK) + INTERVAL 1 WEEK) THEN u.user_id END) AS week10 
 FROM
  users as u
LEFT JOIN
  login_history as lh
    ON u.user_id = lh.user_id
GROUP BY 
    YEAR(u.created), MONTH(u.created)
ORDER BY 
    YEAR(u.created) DESC, MONTH(u.created) DESC
LIMIT 10;

输出为:

monthly, yearly, new_users, week1, week2, week3, week4, week5, week6, week7, week8, week9, week10
3, 2019, 1418, 676, 131, 107, 55, 8, 0, 0, 0, 0, 0
2, 2019, 1452, 707, 241, 234, 239, 202, 157, 93, 32, 2, 0
1, 2019, 2664, 1178, 469, 404, 359, 332, 316, 284, 321, 321, 214
12, 2018, 1574, 340, 50, 88, 53, 17, 47, 50, 29, 48, 19
11, 2018, 1608, 689, 138, 97, 84, 87, 76, 46, 55, 51, 54
10, 2018, 5349, 1817, 763, 691, 656, 585, 531, 478, 465, 455, 422
9, 2018, 5318, 2959, 1295, 1330, 1172, 1101, 1137, 1099, 971, 913, 917
8, 2018, 209, 73, 11, 9, 8, 8, 8, 9, 12, 10, 8
7, 2018, 223, 57, 7, 4, 1, 1, 0, 0, 0, 1, 1
6, 2018, 172, 62, 11, 6, 9, 6, 5, 4, 3, 1, 0