简体   繁体   中英

Mysql: find active users who logged in once a week

I have a table users and another table logins everytime the user log-in into the website we record a row in logins ex.

Users
-----
14 | name1
17 | name2
20 | name3
21 | name4
25 | name5

logins
----
14 | 2015-03-01
14 | 2015-03-07
14 | 2015-03-16
14 | 2015-03-24
14 | 2015-03-30
17 | 2015-03-01
17 | 2015-03-07
17 | 2015-03-16
17 | 2015-03-17
17 | 2015-03-30
20 | 2015-03-01
20 | 2015-03-07
20 | 2015-03-08
20 | 2015-03-16
20 | 2015-03-25
20 | 2015-03-30

if start date is 2015-03-01 and end date is 2015-04-01 then 14 & 20 should be selected while 17 wont be selected since he didn't login in the week of 03-22 to 03-28 so the result would be

   Result
   ------
   2

First you get the list of users per week which has logged in at least once, then you count per month the amount of users:

SELECT LoginYear,LoginWeek,COUNT(*) as NumbUsers
FROM (
  SELECT Year(logins.date) as LoginYear, Week(logins.date) as LoginWeek, logins.UserID
  FROM logins
  WHERE logins.date>='2015-03-01'
  GROUP BY LoginYear, LoginWeek, logins.UserID
  HAVING COUNT(*)>0
) t
GROUP BY LoginYear,LoginWeek;


Week numbering: MySQL can count the weeks in different ways (such as starting on a Sunday/Monday) using the mode: WEEK(date,mode) . See the WEEK MySQL documentation .


Update: to get the number of persons which has been logged in at least once every week: first we get the users that were logged in at least once per week in the subquery weektable . Then the users are select which have a week count which equals the total number of weeks in that period (thus having been online each week). Finally we count those users.

SELECT COUNT(*) 
FROM (
   SELECT UserID
   FROM (
     SELECT Year(logins.date) as LoginYear, Week(logins.date) as LoginWeek, logins.UserID
     FROM logins
     WHERE logins.date>='2015-03-01'
     GROUP BY LoginYear, LoginWeek, logins.UserID
     HAVING COUNT(*)>0
   ) weektable
   GROUP BY UserID
   HAVING COUNT(*)>=TIMESTAMPDIFF(WEEK,'2015-03-01',NOW())
) subq;

Note 1: I put the date '2015-03-01' as an example but you can change this or put as a variable.

Note 2: depending on the dates you choose it can be that the week count by TIMESTAMPDIFF is less than the maximum number of weeks (counted by COUNT(*) ), since it does not count half weeks. Therefore I put >= in the last line: HAVING COUNT(*)>=TIMESTAMPDIFF(WEEK,'2015-03-01',NOW()) .

I cannot test it here at the moment but something like

SELECT COUNT(Users.id) WHERE logins.date>=XXXX AND logins.date<=XXXX GROUP BY Users.id

should work

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM