2014-11-05 90 views
0

我有以下联系表mysql如何获取总数的注册用户在每月

id | date_registered 
1 2014-08-07 
2 2014-08-13 
3 2014-08-14 
4 2014-10-08 
5 2014-10-08 

我想运行一个查询它说告诉我是八月登记在几个月内的用户数, 9月和10月。因此,对于上述数据的查询将返回

8  3 
9  3 
10 5 

这是因为3人在八月加入,直到十月有3人注册,然后另有2人加入制作十月有5。

我已经尝试了以下查询以获得答案(该解决方案在Total number of users at end of each week for last 6 months中采用了类似的方法)。

SELECT MONTH(c1.date_registered) AS month, 
    (SELECT COUNT(c2.id) 
     FROM contacts AS c2 
     WHERE c2.date_registered <= (DATE_FORMAT(DATE_ADD(c1.date_registered, 
                 INTERVAL 1 MONTH),'%Y-%m-01'))) 
     AS 'contacts on system' 
FROM contacts AS c1 
WHERE c1.date_registered BETWEEN '2013-11-01' AND '2014-11-01' 
GROUP BY MONTH(c1.date_registered) 

该查询返回以下结果

month | contacts on system 
8  3 
10  5 

这是不太我想要的东西,因为九月从结果中丢失。

我现在已经完成了几个人提出的建议,并使用了左连接来获得9月的显示。

这是我的新查询

SELECT MONTH(c1.date_registered) AS month, 
    (SELECT COUNT(c2.id) 
     FROM contacts AS c2 
     WHERE c2.date_registered <= (DATE_FORMAT(DATE_ADD(c1.date_registered, 
                 INTERVAL 1 MONTH),'%Y-%m-01'))) 
     AS ContactsOnSystem 
FROM (select 8 as mon union 
    select 9 as mon union 
    select 10 as mon 
) as m left join 
contacts as c1 
on MONTH(c1.date_registered) = m.mon 
GROUP BY MONTH(c1.date_registered) 

当此查询时,它会返回

month | ContactsONSystem 
9  0 
8  3 
10  5 

哪个是更好的,但仍然不是我后。我想要说的是,9月份系统中有3个联系人不是0.在8月份注册的3个人仍然在9月注册,因为他们没有去过任何地方。

明白了在第三次尝试工作

SELECT m.mon AS month, (SELECT COUNT(c2.id) 
         FROM contacts AS c2 
         WHERE c2.date_registered < m.monthstart) AS ContactsOnSystem 
FROM (select '2014-09-01' as monthstart, 8 as mon union 
     select '2014-10-01' as monthstart, 9 as mon union 
     select '2014-11-01' as monthstart, 10 as mon 
) as m LEFT JOIN 
contacts as c1 
on MONTH(c1.date_registered) = m.mon 
GROUP BY MONTH(c1.date_registered) 
+0

好吧,在你的表中9月份没有注册用户,所以你的查询输出是正常的。 – 2014-11-05 11:46:14

+0

您必须加入另一个包含月份的表(或每个月的第一个日期) 以前2014-08-01,2014-09-01,2014-10-01,2014-11-01,2014- 12-01,.... – 2014-11-05 11:49:33

回答

2

完全加入包含月份的表格。 筛选具有比此行“all-month-list”-date更早的registerdate的数据集。

自您注册以来,每个用户每月会得到一个条目。

此外,您可以像之前说过的那样进行分组。

+0

啊我明白你的意思了。对不起,我误解了。对,我会放弃这一点。谢谢。 – 2014-11-05 12:37:17

+0

是的,它的作品。谢谢。 – 2014-11-05 12:44:02

0

你可以做你想要明确列出个月,并使用left join什么:

SELECT m.mon AS month, count(c1.date_registered) as ContactsOnSystem 
FROM (select 2014 as yr, 8, 201408 as yyyymm as mon union all 
     select 2014, 9, 201409 union all 
     select 2014, 10, 201410 
    ) m left join 
    contacts c1 
    on yyyymm between year(c1.date_registered) * 100 + month(c1.date_registered) 
GROUP BY yyyymm, mon 
ORDER B yyyymm; 

作为一个说明:不要使用单引号列别名。只对字符串和日期常量使用单引号。

0

您的查询的输出是正常的,因为在MySQL中无法显示没有数据的箭头。证明:

[email protected]:~$ mysql -u root -p 
Enter password: 
Welcome to the MySQL monitor. Commands end with ; or \g. 
Your MySQL connection id is 48 
Server version: 5.5.40-0ubuntu0.12.04.1 (Ubuntu) 

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. 

Oracle is a registered trademark of Oracle Corporation and/or its 
affiliates. Other names may be trademarks of their respective 
owners. 

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. 

mysql> create database SOtest; 
Query OK, 1 row affected (0.00 sec) 

mysql> use SOtest; 
Database changed 
mysql> create table test (id INT, data VARCHAR(10)); 
Query OK, 0 rows affected (0.16 sec) 

mysql> insert into test (id, data) values(0,'data0'); 
Query OK, 1 row affected (0.07 sec) 

mysql> insert into test (id, data) values(1,'data1'); 
Query OK, 1 row affected (0.06 sec) 

mysql> insert into test (id) values(2); 
Query OK, 1 row affected (0.08 sec) 

mysql> select * from test where data !='begueradj'; 
+------+-------+ 
| id | data | 
+------+-------+ 
| 0 | data0 | 
| 1 | data1 | 
+------+-------+ 
2 rows in set (0.00 sec) 

mysql> 

正如你所看到的,不显示第3行。这是MySQL的正常行为。

0

将您的输出连接到包含月份数与外连接的表中以获得9 |已添加0个。

+0

这还不够。我上面编辑了我的帖子,告诉你为什么。 – 2014-11-05 12:26:46