2013-04-02 13 views
8

Ich habe eine Tabelle für meine Benutzer, die ein Feld namens "erstellt" haben, die das Registrierungsdatum haben.Mysql Abfrage, um die Anzahl pro Monate zu erhalten

Wie kann ich eine Liste erhalten, die die Anzahl der Anmeldungen pro Monat in den letzten 12 Monaten enthält? So:

Month Count 
1  1232 
2  2222 
3   122 
4  4653 
...  ... 
12  7654 

ich die Arbeit mit MySQL nicht verwendet, so dass ich nur bis jetzt weiß, wie die Anzahl der Registrierungen im vergangenen Jahr zu zählen, nicht, wie die von letzten 12 Monaten zählen zur Gruppe. Danke im Voraus!

UPDATE

Nun ist diese erhalte ich, @fthiella-Lösung:

+------------------------------+-------------------------------+----------+ 
| Year(FROM_UNIXTIME(created)) | Month(FROM_UNIXTIME(created)) | Count(*) | 
+------------------------------+-------------------------------+----------+ 
|       2012 |        4 |  9927 | 
|       2012 |        5 |  5595 | 
|       2012 |        6 |  4431 | 
|       2012 |        7 |  3299 | 
|       2012 |        8 |  429 | 
|       2012 |       10 |  3698 | 
|       2012 |       11 |  6208 | 
|       2012 |       12 |  5142 | 
|       2013 |        1 |  1196 | 
|       2013 |        2 |  10 | 
+------------------------------+-------------------------------+----------+ 

Wie ich Abfrage zwingen kann mich mit count = 0 die Monate zu geben?

Lösung von @fthiella (vielen Dank!):

 SELECT y, m, Count(users.created) 
    FROM (
     SELECT y, m 
     FROM 
     (SELECT YEAR(CURDATE()) y UNION ALL SELECT YEAR(CURDATE())-1) years, 
     (SELECT 1 m UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 
      UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 
      UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12) months) ym 
     LEFT JOIN users 
     ON ym.y = YEAR(FROM_UNIXTIME(users.created)) 
      AND ym.m = MONTH(FROM_UNIXTIME(users.created)) 
    WHERE 
     (y=YEAR(CURDATE()) AND m<=MONTH(CURDATE())) 
     OR 
     (y<YEAR(CURDATE()) AND m>MONTH(CURDATE())) 
    GROUP BY y, m; 

Und die Ergebnisse:

+------+----+----------------------+ 
| y | m | Count(users.created) | 
+------+----+----------------------+ 
| 2012 | 5 |     5595 | 
| 2012 | 6 |     4431 | 
| 2012 | 7 |     3299 | 
| 2012 | 8 |     429 | 
| 2012 | 9 |     0 | 
| 2012 | 10 |     3698 | 
| 2012 | 11 |     6208 | 
| 2012 | 12 |     5142 | 
| 2013 | 1 |     1196 | 
| 2013 | 2 |     10 | 
| 2013 | 3 |     0 | 
| 2013 | 4 |     0 | 
+------+----+----------------------+ 

Antwort

9

Wenn erstellt ein INT-Feld, Sie FROM_UNIXTIME Funktion sollte es ein konvertieren Datumsfeld und dann MONTH Funktion, um den Monat zu extrahieren:

zählt alle Zeilen, die in den letzten 12 Monaten erstellt wurden. Bitte beachten Sie, dass es wahrscheinlich besser, auch Gruppe durch das Jahr:

SELECT Year(FROM_UNIXTIME(created)), Month(FROM_UNIXTIME(created)), Count(*) 
FROM yourtable 
WHERE FROM_UNIXTIME(created) >= CURDATE() - INTERVAL 1 YEAR 
GROUP BY Year(FROM_UNIXTIME(created)), Month(FROM_UNIXTIME(created)) 

Wenn Sie die Registrierungsnummern anstelle der Zeilen zählen benötigen, können Sie so etwas wie

COUNT(registration_number) 

überspringen Nullwerte verwenden könnte, oder

COUNT(DISTINCT registration_number) 

nur einzelne zu zählen.

bearbeiten

Wenn Sie auch Monate müssen zeigen, dass Anzahl haben = 0, würde ich eine Abfrage wie folgt verwenden, die alle Monate für das laufende und für das vergangene Jahr zurück:

SELECT y, m 
FROM 
    (SELECT YEAR(CURDATE()) y UNION ALL SELECT YEAR(CURDATE())-1) years, 
    (SELECT 1 m UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 
    UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 
    UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12) months; 

und dann würde ich eine LEFT JOIN, die alle Zeilen der ersten Abfrage gibt, und nur die Zeilen der zweiten Abfrage, die übereinstimmt:

SELECT y, m, Count(yourtable.created) 
FROM (
    SELECT y, m 
    FROM 
    (SELECT YEAR(CURDATE()) y UNION ALL SELECT YEAR(CURDATE())-1) years, 
    (SELECT 1 m UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 
     UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 
     UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12) months) ym 
    LEFT JOIN yourtable 
    ON ym.y = YEAR(FROM_UNIXTIME(yourtable.created)) 
    AND ym.m = MONTH(FROM_UNIXTIME(yourtable.created)) 
WHERE 
    (y=YEAR(CURDATE()) AND m<=MONTH(CURDATE())) 
    OR 
    (y<YEAR(CURDATE()) AND m>MONTH(CURDATE())) 
GROUP BY y, m 

(bitte beachten Sie, dass ich hier nur die letzten 12 Monate in Betracht ziehe, also wenn wir Mitte April 2013 sind, zählt es Zeilen im Intervall Mai 2012 - 13. April, wenn dies nicht das richtige Verhalten ist, lass es mich wissen)

+0

mein Das erstellte Feld ist ein int-Feld, da mein Registrierungsdatum im Timestamp-Format ist ... –

+0

'MONTH (FROM_UNIXTIME (your_field))' sollte funktionieren – Vatev

+0

@DavidR Ich habe meine Antwort aktualisiert, es sollte nicht korrekt sein – fthiella

9
SELECT MONTH(reg_date) , COUNT(reg_date) 
FROM your_table 
WHERE reg_date >= NOW() - INTERVAL 1 YEAR 
GROUP BY MONTH(reg_date) 
+0

Es zeigt für die MOnths, deren Datensätze in der Datenbank verfügbar sind. Wie würde ich es für den ganzen Monat machen? Mittel von 1-12 Monaten. ?? – Sankalp

+0

Überprüfen Sie die andere Antwort :) – Vatev

0

Falls dies hilft jemand anderes, ich zusätzlich diese Abfrage wollte, aber für ein bestimmtes Zeitintervall, das nicht unbedingt in den letzten 12 Monaten (auch mit einem Zeitstempel für das Datum):

set @start='2013-05-01 00:00:00'; 
set @end='2015-03-31 00:00:00'; 

SELECT YEAR(FROM_UNIXTIME(yourtable.created_date)), MONTH(FROM_UNIXTIME(yourtable.created_date)), COUNT(yourtable.created_date) 
FROM yourtable 
WHERE created_date BETWEEN UNIX_TIMESTAMP(DATE(@start)) AND UNIX_TIMESTAMP(DATE(@end)) 
GROUP BY YEAR(FROM_UNIXTIME(yourtable.created_date)), MONTH(FROM_UNIXTIME(yourtable.created_date)) 
ORDER BY YEAR(FROM_UNIXTIME(yourtable.created_date)), MONTH(FROM_UNIXTIME(yourtable.created_date)); 
Verwandte Themen