2009-03-05 10 views
2

Je veux récupérer le nombre de registrations d'une période donnée (disons une semaine), ce qui n'est pas si difficile à faire, mais je me demandais si est en tout cas possible à MySQL de retourner un zéro pour les jours qui n'ont pas d'enregistrements.Comment récupérer les données de Mysql pour les jours sans statistiques

Un exemple: DONNÉES:

 
ID_Profile datCreate 
1 2009-02-25 16:45:58 
2 2009-02-25 16:45:58 
3 2009-02-25 16:45:58 
4 2009-02-26 10:23:39 
5 2009-02-27 15:07:56 
6 2009-03-05 11:57:30 

SQL:

 
    SELECT 
     DAY(datCreate) as RegistrationDate, 
    COUNT(ID_Profile) as NumberOfRegistrations 
    FROM tbl_profile 
    WHERE DATE(datCreate) > DATE_SUB(CURDATE(),INTERVAL 9 DAY) 
    GROUP BY RegistrationDate 
    ORDER BY datCreate ASC; 

Dans ce cas, le résultat serait:

 
RegistrationDate NumberOfRegistrations 
25 3 
26 1 
27 1 
5 1 

Il est évident que je suis absent quelques jours entre. Actuellement je résous ceci dans mon code php, mais je me demandais si MySQL avait un moyen de renvoyer automatiquement 0 pour les jours/lignes manquants. Ce serait le résultat souhaité:

 
RegistrationDate NumberOfRegistrations 
25 3 
26 1 
27 1 
28  0 
1  0 
2  0 
3  0 
4  0 
5 1 

De cette façon, nous pouvons utiliser MySQL pour résoudre tous les problèmes concernant le nombre de jours dans un mois au lieu de compter sur le code php pour calculer pour chaque mois combien de jours il y a, depuis MySQL a cette version de fonctionnalité.

Merci à l'avance

Répondre

4

Non, mais une solution de contournement serait de créer une table à colonne unique avec une clé primaire de la date, pré-chargé avec des dates pour chaque jour. Vous auriez des dates de votre premier point de départ jusqu'à un avenir lointain.

Maintenant, vous pouvez laisser vos données statistiques à gauche - alors vous obtiendrez des valeurs nulles pour ces jours sans données. Si vous voulez vraiment un zéro plutôt qu'un zéro, utilisez IFNULL(colname, 0)

+0

@Paul - Vous me battez pour ça. Y at-il un moyen de définir une valeur par défaut de zéro, de sorte que la jointure à gauche mettra un zéro au lieu de null pour les jours sans données? –

+0

Oui, utilisez IFNULL (col, 0) –

+0

Est-ce que cela veut dire que vous avez une table contenant simplement toutes les dates à partir de maintenant jusqu'à la fin de chaque fois que vous souhaitez arrêter de faire des statistiques? Fondamentalement une table avec 365 dossiers par an? Merci pour la réponse rapide. – n0xie

1

Grâce à Paul Dixon, j'ai trouvé la solution. Tout d'abord intéressé par la façon dont j'ai résolu cela lire:

D'abord créer une procédure stockée J'ai trouvé quelque part pour remplir un tableau avec toutes les dates de cette année.

 
CREATE Table calendar(dt date not null); 

CREATE PROCEDURE sp_calendar(IN start_date DATE, IN end_date DATE, OUT result_text TEXT) 
    BEGIN 
    SET @begin = 'INSERT INTO calendar(dt) VALUES '; 
    SET @date = start_date; 
    SET @max = SUBDATE(end_date, INTERVAL 1 DAY); 
    SET @temp = ''; 
    REPEAT 
     SET @temp = concat(@temp, '(''', @date, '''), '); 
     SET @date = ADDDATE(@date, INTERVAL 1 DAY); 
     UNTIL @date > @max 
    END REPEAT; 
    SET @temp = concat(@temp, '(''', @date, ''')'); 
    SET result_text = concat(@begin, @temp); 
    END 


    call sp_calendar('2009-01-01', '2010-01-01', @z); 

    select @z; 

Ensuite, changez la requête pour ajouter la jointure gauche:

 
SELECT 
    DAY(dt) as RegistrationDate, 
    COUNT(ID_Profile) as NumberOfRegistrations 
FROM calendar 
LEFT JOIN 
    tbl_profile ON calendar.dt = tbl_profile.datCreate 
WHERE dt BETWEEN DATE_SUB(CURDATE(),INTERVAL 6 DAY) AND CURDATE() 
GROUP BY RegistrationDate 
ORDER BY dt ASC 

Et nous sommes fait.

Merci à tous pour les réponses rapides et la solution.

Questions connexes