2016-02-04 149 views
3

我需要查询Mysql来查找日期范围内每个月的活动用户数。活跃用户是在本月和之前的月份拥有登录日志记录的用户(两个月不仅仅是其中的一个月)。MySql查询每月对活动用户进行计数的脚本

这是一个表和测试数据的脚本。

CREATE TABLE `logger` (
    `id` INTEGER NULL AUTO_INCREMENT DEFAULT NULL, 
    `UserId` INTEGER NULL DEFAULT NULL, 
    `loginDate` DATE NULL DEFAULT NULL, 
    PRIMARY KEY (`id`) 
); 

INSERT INTO `logger` (`UserId`,`loginDate`) VALUES 
('1001','20151109'), 
('1002','20151103'), 
('1003','20151111'), 
('1002','20151205'), 
('1003','20151208'), 
('1001','20160103'), 
('1002','20160105'); 

我需要这样的结果对于像20151201一至20160201

------------------------------ 
year |month |users |activeUsers 
2015 |12 |2  |2 
2016 |01 |2  |1 // only uid 1002 have activity in past month 20151205 

准备使用在线表格http://sqlfiddle.com/#!9/e9881

+0

'(“1001”,“20160103”)'VS“只有UID 1002在过去一个月的活动”哪一个是什么呢? – miken32

+0

另外一个好主意来编辑你的问题,并包括你到目前为止尝试过的。 – miken32

+0

@ miken32 this one - >('1002','20151205') – Reza

回答

5

您可以使用的方法来做到这点。单月从每个日期添加,然后你可以使用union allaggregation的计数:

select year(logindate), month(logindate), count(distinct userid) 
from ((select logindate, userid 
     from logger 
    ) union all 
     (select date_add(longdate, interval 1 month), userid 
     from logger 
    ) 
    ) l 
group by year(logindate), month(logindate) 
order by 1, 2; 

编辑:

哦,我误解了这个问题。您需要连续两个月才能成为活跃用户。我了解用户登录会使用户激活两个月。好了,你可以用joinexists解决这个问题:

select year(l.logindate), month(l.logindate), count(distinct l.userid) 
from logger l 
where exists (select 1 
       from logger l2 
       where l2.userid = l.userid and 
        year(date_sub(l.logindate, interval 1 month)) = year(l2.logindate) and 
        month(date_sub(l.logindate, interval 1 month)) = month(l2.logindate) 
      ) 
group by year(l.logindate), month(l.logindate); 
+0

这里是结果,最后一条记录不正确http://sqlfiddle.com/#!9/e9881/27 – Reza

+0

@Reza。 。 。这将包括未来一个月。它符合你的定义。但是,如果你想排除它,你可以添加'有计数(不同的月份(logindate))= 2'。 –

+0

好吧,看起来我们接近结果,但它仍然给我一个**错误的结果**,因为**它计算的用户在过去一个月登录但在本月没有登录,他们不再活跃* *,我应该为2016-01和2015-12分别获得1个用户和2个用户,但是您的查询会给我3个用户,这是错误的。我测试也有线,它什么都没有返回! – Reza