2016-10-04 1 views
1

j'ai une requête SQL comme ceci:Groupe par comptage (*) et 0 au lieu de vide

SELECT date_format(`user_date_accountcreated`, "%Y-%m-%d") as date, Count(*) as total from users 
where `user_date_accountcreated` 
BETWEEN '2016-09-18 00:00:00' AND '2016-10-03 23:59:59' 
GROUP BY date_format(`user_date_accountcreated`, "%y%m%d") 

Mais quand il n'y a pas Reccords, je résultat vide à cause de GROUP BY, il n'y a rien à groupe. ..

J'ai essayé avec ISNULL comme ceci:

SELECT date_format(`user_date_accountcreated`, "%Y-%m-%d") as date, ISNULL(Count(*), 0) as total from users 
where `user_date_accountcreated` BETWEEN '2016-09-18 00:00:00' AND '2016-10-03 23:59:59' 
GROUP BY date_format(`user_date_accountcreated`, "%y%m%d") 

Mais je reçois une erreur SQL: # 1582 - nombre de paramètres incorrect dans l'appel à la fonction native 'ISNULL'

Une chance d'obtenir 0 au lieu du résultat vide lorsque nous utilisons un GROUP BY?

+0

count() est une fonction d'agrégation. son résultat n'est pas disponible avant que toutes les lignes aient été prises en compte. Vous l'utilisez dans une fonction isnull(), qui est évaluée sur une base par ligne. Les bases de données ne peuvent pas voyager dans le temps, elles ne peuvent donc pas fournir rétroactivement une valeur de comptage "final" (*) à isnull au moment où l'isnull est réellement évalué. et bien sûr, RTFM: [isnull()] (http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_isnull) il ne prend qu'un argument, exactement comme votre erreur l'indique. –

+0

vous voulez probablement [coalesce()] (http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_coalesce) à la place. –

+0

@MarcB Je pense que son problème est que la condition «WHERE» filtre complètement les enregistrements, laissant son ensemble de résultats manquer certaines données au fil du temps, car il ne correspondait pas aux critères. La vérification de 0, null, etc., ne portera pas ses fruits car les documents ne seront tout simplement pas là. –

Répondre

1

Utiliser l'agrégation conditionnelle:

SELECT DATE_FORMAT(user_date_accountcreated, "%Y-%m-%d") AS date, 
     SUM(CASE WHEN user_date_accountcreated BETWEEN '2016-09-18 00:00:00' AND 
                '2016-10-03 23:59:59' 
      THEN 1 ELSE 0 END) AS total_from_users 
GROUP BY DATE_FORMAT(user_date_accountcreated, "%y%m%d") 
+0

@JaydipJ Oui, bien sûr, merci. –

+0

Je reçois des résultats étranges à partir de 2014-01-01 comme date (Le début des dates dans la table) jusqu'au 2014-01-25 et tous les résultats sont NULL. –

+0

@LondonSmith Veuillez réessayer, j'ai modifié l'instruction 'CASE' pour renvoyer une somme de' 0' s'il n'y a pas d'enregistrements correspondants pour un groupe donné. Auparavant, j'avais omis ceci, ce qui pourrait expliquer pourquoi vous obteniez des valeurs 'NULL' dans des endroits que vous n'attendiez pas. –

0

Cocher cette

SELECT 
    date_format(`user_date_accountcreated`, "%Y-%m-%d") as date, 
    Count(date_format(`user_date_accountcreated`, "%Y-%m-%d")) as total 
from users 
where `user_date_accountcreated` 
BETWEEN '2016-09-18 00:00:00' AND '2016-10-03 23:59:59' 
GROUP BY date_format(`user_date_accountcreated`, "%y%m%d") 
+0

Aucune différence, largeur des dates, aucun résultat n'apparaît. –

0

d'abord une requête ne peut pas renvoyer les enregistrements qui ne sont pas là. Si vous voulez les voir, vous devrez les générer. La requête suivante utilise UNION ALL pour soit obtenir les enregistrements de votre requête ou un enregistrement généré lorsque votre requête renvoie aucune ligne:

SELECT 
    date_format(user_date_accountcreated, '%Y-%m-%d') AS date, 
    COUNT(*) AS total 
FROM users 
WHERE user_date_accountcreated >= '2016-09-18' 
    AND user_date_accountcreated < '2016-10-04' 
GROUP BY date_format(user_date_accountcreated, '%Y-%m-%d') 
UNION ALL 
SELECT null, 0 
WHERE NOT EXISTS 
(
    SELECT * 
    FROM users 
    WHERE user_date_accountcreated >= '2016-09-18' 
    AND user_date_accountcreated < '2016-10-04' 
); 

La même chose peut être obtenue avec une avec clause:

WITH mydates AS 
(
    SELECT 
    date_format(user_date_accountcreated, '%Y-%m-%d') AS date, 
    COUNT(*) AS total 
    FROM users 
    WHERE user_date_accountcreated >= '2016-09-18' 
    AND user_date_accountcreated < '2016-10-04' 
    GROUP BY date_format(user_date_accountcreated, '%Y-%m-%d') 
) 
SELECT date, total FROM mydates 
UNION ALL 
SELECT null, 0 WHERE NOT EXISTS (select * from mydates); 

I avons également corrigé deux erreurs dans votre requête:

  • Le séparateur de chaîne SQL est ' comme dans '%Y-%m-%d'.
  • Votre liste de sélection doit contenir la même valeur que dans le groupe par ('%Y-%m-%' vs '%y%m%d'). Cela fonctionne dans votre cas, mais pourrait causer des problèmes dans d'autres situations.
+0

Oui, je comprends mes 2 erreurs. Pour les résultats, je n'ai pas de dates avec 0, elles n'apparaissent pas. –

+1

@LondonSmith Si votre table d'origine manque d'enregistrements pour certaines dates, ces dates ne figureront absolument dans aucune des solutions données. Dans ce cas, vous devrez peut-être utiliser une table de calendrier pour importer des données manquantes. –

+0

Oui @TimBiegeleisen Je vais faire les choses en PHP au lieu d'utiliser un calendrier. Merci :) –