2014-11-05 32 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