[MySQL] Astuce pour qu'un count( ) vide retourne la valeur 0 ?

Astuce pour qu'un count( ) vide retourne la valeur 0 ? [MySQL] - SQL/NoSQL - Programmation

Marsh Posté le 21-08-2003 à 18:26:50    

Bonjour,
J'effectue sous mysql un count sur une table et pour une valeur précise, j'ai count()=0, mais mysql ne m'affiche pas la ligne de résultat
 
Y-a-t-il une astuce pour afficher le 0 lors du calcul du count().
 
Merci


Message édité par Lra|zr le 21-08-2003 à 18:35:52
Reply

Marsh Posté le 21-08-2003 à 18:26:50   

Reply

Marsh Posté le 21-08-2003 à 18:29:02    

if (empty($tonresultat))
{
$tonresultat = 0;
}
 
a moins que tu veux uniquement en mysql ?

Reply

Marsh Posté le 21-08-2003 à 18:35:26    

oui, c'est de la syntaxe mysql que je cherche car c'est à ce niveau que le count ne me retourne pas de valeur nulle.

Reply

Marsh Posté le 21-08-2003 à 20:31:53    

C'est quoi ta requête ? count() renvoie toujours 1 ligne :heink:

Reply

Marsh Posté le 21-08-2003 à 23:46:36    

je vais surement traiter le truc différement mais je continue juste pour l'histoire du "count() vide".
 
Un exemple simple : une table contenant des noms et je souhaite avoir le nombre de personnes s'appelant durand
 
SELECT nom,count(*) FROM `emailing_dup` WHERE nom='durand' GROUP BY nom
->durand : 4
 
maintenant le nb de personnes s'appelant durandd, dans ma base y'en a pas donc select vide donc count(*)=0 mais mysql ne me renvoie aucune donnée
 
Voila pourquoi je dis que count ne retourne rien
Y a t-il moyen de forcer l'affichage de la valeur 0 ?
 
Mon vrai pb est que je fais un enchainement de count et donc si j'ai du blanc à la place de 0, je perds des valeurs
 
Je pense que vais essayer de trouver une autre solution :D
 
merci
A+

Reply

Marsh Posté le 21-08-2003 à 23:48:55    

SELECT nom,count(*) FROM `emailing_dup` WHERE nom='durand' GROUP BY nom
 
elle est bizarre cette requête. Pourquoi tu fais un group by sur le nom alors que tu te limite à un nom particulier (par le WHERE) :??:
SELECT count(*) FROM `emailing_dup` WHERE nom='durand'
 
edit : à mon avis, c'est le group by avec une occurence qui n'existe pas qui pose problème [:figti]  
je testerais demain :)  
 
Ou alors :
SELECT nom, count(*) FROM `emailing_dup` GROUP BY nom
pour avoir tous les noms, avec le nombre d'occurences pour chacun :)


Message édité par mrbebert le 21-08-2003 à 23:52:57
Reply

Marsh Posté le 21-08-2003 à 23:49:22    

ca m'interesse bcp aussi tiens ! :)

Reply

Marsh Posté le 21-08-2003 à 23:52:41    

c'est pas à cause du count que la requete ne retourne rien mais à cause du where :
SELECT nom,count(*) FROM `emailing_dup` WHERE nom='durandd' GROUP BY nom  
 
si personne ne s'appelle durandd la requete ne retourne rien (encore heureux ;) )
 
moi je ferais (en php)
 
$result = mysql_query("SELECT nom,count(*) FROM `emailing_dup` WHERE nom='durandd' GROUP BY nom" );
$nb = (!$result)?0:mysql_num_rows($result);
echo "durandd : ".$nb;
 
 
Ps: pas sur de la syntaxe :p

Reply

Marsh Posté le 21-08-2003 à 23:55:50    

:non:  
 
(!$result)?0:mysql_num_rows($result);
 
s'interprète de la manière suivant :
s'il y a une erreur de requête, renvoyer 0 sinon renvoyer mysql_num_rows($result).
Mais il y a une différence entre une requête ayant une erreur et une requête renvoyant 0 ligne (ce qui est un résultat comme un autre) [:proy]


Message édité par mrbebert le 21-08-2003 à 23:57:00
Reply

Marsh Posté le 22-08-2003 à 00:05:38    

enlève le "nom" du select, tu auras 0 comme résultat.
 
et tu n'a pas besoin de ce nom, puisqu'il est déjà dans une variable.

Reply

Marsh Posté le 22-08-2003 à 00:05:38   

Reply

Marsh Posté le 22-08-2003 à 00:09:07    

oui mais d'autres cas ou on peut pas changer ou faire par php ?  
on peut pas forcer l'affichage, au moins d'un NULL ?

Reply

Marsh Posté le 22-08-2003 à 00:13:51    

bah c'est simple : il suffit de faire :
 
SELECT 1 as req, nom,count(*) FROM `emailing_dup` WHERE nom='durand' GROUP BY nom  
union
select 2 as req, '', 0
order by req
 
Et zou :)
 
Tu ne regarde que la première ligne. Si count != 0 alors il sera de toute façon la première ligne retrournée. Sinon, bah y'aura 0 :)

Reply

Marsh Posté le 22-08-2003 à 00:15:07    

Peut être ca :
SELECT nom,count(*) FROM `emailing_dup` WHERE nom='durand'  :??:  
 
et si ca marche en mettant un NULL à la place du nom lorsqu'il n'y a aucune occurence, tu pourras toujours faire ca :
SELECT IFNULL(nom, 'durand'), count(*) FROM `emailing_dup` WHERE nom='durand' :)

Reply

Marsh Posté le 22-08-2003 à 00:23:58    

merci des réponses
Je suis en effet d'accord que vue que le select était vide, count ne pouvait etre appliqué mais y a t-il moyen de fixer sa valeur à 0 ?
 
Mon vrai pb (j'ai voulu faire simple pour pas faire fuire les potentiels sauveurs  :D mais vu k'il ya des motiV ) :
 
SELECT SUBSTRING(date_envoi,1,6) as mois,count(*) as nombre FROM `emailing` WHERE (date_envoi>20030600000000) AND (date_envoi<20030800000000) AND (methode='La radio') GROUP BY SUBSTRING(date_envoi,1,6);
 
Je cherche le nb de personnes ayant répondu la réponse  
'La radio' entre début juin et fin juillet 2003.
Dans mon cas : 0 en juin, 2 en juillet
mais la req ne retourne que la valeur 2.
 
Toute proposition/solution est la bienvenue  ;)  
Merci
 
edit : j'avais pas lu ttes les réponses, j'essaierais ca demain, merci à tous


Message édité par Lra|zr le 22-08-2003 à 00:26:23
Reply

Marsh Posté le 22-08-2003 à 00:40:13    

MagicBuzz a écrit :

bah c'est simple : il suffit de faire :
 
SELECT 1 as req, nom,count(*) FROM `emailing_dup` WHERE nom='durand' GROUP BY nom  
union
select 2 as req, '', 0
order by req
 
Et zou :)
 
Tu ne regarde que la première ligne. Si count != 0 alors il sera de toute façon la première ligne retrournée. Sinon, bah y'aura 0 :)


 
UNION est à partir de mysql 4.0.0 or je suis en 3.23.43

Reply

Marsh Posté le 22-08-2003 à 00:52:43    

Lra|zr a écrit :


 
UNION est à partir de mysql 4.0.0 or je suis en 3.23.43  


bah il ne reste plus que la solution de virer le "nom", qui de toute façon ne sert strictement à rien.
 
et à ce moment, ça marchera forcément (ou alors MySQL ne respecte pas l'once d'une ligne de la norme SQL-92)
alors certes, MySQL y fait pas mal d'entorses, mais je pense pas que ça aille jusque là.

Reply

Marsh Posté le 22-08-2003 à 00:53:58    

sans nom :
 
SELECT count(*) FROM `emailing_dup` WHERE nom='durand'
 
si tu veux absoluement conserver nom :
 
SELECT '$nom',count(*) FROM `emailing_dup` WHERE nom='$nom' GROUP BY '$nom'


Message édité par MagicBuzz le 22-08-2003 à 00:54:40
Reply

Marsh Posté le 22-08-2003 à 09:39:43    

MagicBuzz a écrit :

sans nom :
 
SELECT count(*) FROM `emailing_dup` WHERE nom='durand'
 


 
en effet, ca marche bien ca
Ca affiche bien 0 si le nom cherché est inexistant
 
J'ai un autre exemple pour lequel ca ne fonctionne pas :  
 
SELECT count(*) FROM `emailing` WHERE (date_envoi>20030600000000) AND (date_envoi<20030800000000) AND (methode='La radio') GROUP BY SUBSTRING(date_envoi,1,6);
 
en juin : 0 personne ont répondu 'La radio' donc count(*) = 0 et en juillet : 2 personnes or ma requete me retourne uniquement le 2
 
Y a un moyen de solutionner cela ?
Merci à tous
A+

Reply

Marsh Posté le 22-08-2003 à 11:02:12    

Le moyen le plus simple est de créer une table temporaire contenant tous les mois.
 
Et de faire ta requête en faisant une jointure externe dessus.
 
Une autre solution consiste à passer par des union et des sous-requêtes, mais vu que ta version de MySQL ne supporte pas, c'est rappé.

Reply

Marsh Posté le 22-08-2003 à 11:10:51    

ok, je vais changer de voie
 
sinon j'avais mis tout mes espoirs la dedans mais non :
 
SELECT IFNULL(COUNT(*),0) FROM `emailing` WHERE (date_envoi>20030600000000) AND (date_envoi<20030800000000)  
AND (methode='La Radio') GROUP BY SUBSTRING(date_envoi,1,6)
 
surement le GROUP BY qui fait chier mais si je le mets pas je ne peux plus faire le calcul sur un mois entier
 
merci tlm

Reply

Marsh Posté le 22-08-2003 à 13:36:33    

Non, ton isnull ne sert à rien.
 
COUNT() ne revoit jamais null. Mais dans ton cas, il ne rammène tout simplement pas de ligne du tout.
 
Il te faut obligatoirement une table de référence avec tous les mois pour le forcer à retourner des valeurs pour chaque mois. Sinon, il sera incapable d'inventer les mois pour toi.

Reply

Marsh Posté le 22-08-2003 à 18:07:51    

MagicBuzz a écrit :


 
Il te faut obligatoirement une table de référence avec tous les mois pour le forcer à retourner des valeurs pour chaque mois. Sinon, il sera incapable d'inventer les mois pour toi.


 
J'ai fais une table 'mois_indic' des mois 200306,200307,...
 
SELECT count(*) FROM `emailing` LEFT JOIN mois_indic ON mois_indic.date_envoi=SUBSTRING(emailing.date_envoi,1,6) WHERE (emailing.date_envoi>20030600000000) AND (emailing.date_envoi<20030800000000) AND (methode='La radio') GROUP BY SUBSTRING(emailing.date_envoi,1,6);
 
Je n'ai pas le 0.
Si tu vois ski cloche, au plaisir  ;)  
Merci bien de ton aide
A+

Reply

Marsh Posté le 22-08-2003 à 19:24:47    

left outer join (ou right outer join, chais jamais :D)

Reply

Marsh Posté le 22-08-2003 à 22:29:02    

select max(count(),0)  
ca marcherait pas ca ?

Reply

Marsh Posté le 23-08-2003 à 02:01:46    

pas plus.
 
zéro ligne, c'est zéro ligne. c'est pas une valeur. c'est rien. donc ton max, il va même pas chercher à l'éxécuter. pour qu'une fonction d'agrégation fonctionne encore faut-il qu'il y ait des données pour se baser dessus.

Reply

Marsh Posté le 24-08-2003 à 21:22:27    

Ca marche tjrs pas et cette solution me ferais gagner des requetes :
 
J'ai donc 2 tables :
emailing :
id,methode,date
1 La radio  20030610101112
2 La presse 20030704111213
3 La presse 20030708141219
 
mois_indic :
date
200306
200307
 
Je cherche à récupérer le nombre de personnes ayant répondu "La presse" entre juin et juillet 2003, trié par mois
Mon but, sur mon exemple, est d'obtenir :
0
2
 
J'effectue donc la req suivante :

Code :
  1. SELECT count(*) FROM `emailing` LEFT OUTER JOIN mois_indic ON mois_indic.date_envoi=SUBSTRING(emailing.date_envoi,1,6) WHERE (emailing.date_envoi>20030600000000) AND (emailing.date_envoi<20030800000000) AND (methode='La radio') GROUP BY SUBSTRING(emailing.date_envoi,1,6);

 
 
et je n'obtiens que le 2
Si quelqu'un voit ce que j'ai mal fait
Merci bien
A+


Message édité par Lra|zr le 24-08-2003 à 21:24:17
Reply

Marsh Posté le 24-08-2003 à 23:26:33    

essaie right outer join


Message édité par MagicBuzz le 24-08-2003 à 23:26:43
Reply

Marsh Posté le 24-08-2003 à 23:35:17    

généralement, c'est left que l'on utilise
mais bon, j'ai toujours la mm réponse (2) avec right
 
je suis tjrs preneur de solution car c'est bien la création d'une table des mois qui devrait régler ce pb (merci MagicBuzz  ;) )

Reply

Marsh Posté le 24-08-2003 à 23:36:11    

Oui, avec la création d'une table des mois, il n'y aurait pas de problème :)
C'est toujours compliqué de faire des requête qui "inventent" de l'information (un total pour un mois qui n'apparait nul part) :pt1cable:


Message édité par mrbebert le 24-08-2003 à 23:37:18
Reply

Marsh Posté le 19-04-2016 à 17:30:10    

Le plus simple est de faire un UNION suivi d'un LIMIT 1
 
Select count() ... UNION select 0 ... LIMIT 1;

Reply

Marsh Posté le 20-04-2016 à 10:50:40    

Déterrage en or....

Reply

Marsh Posté le 21-04-2016 à 09:50:45    

J'avais pas vu la date du topic. C'est quand j'ai lu "UNION est à partir de mysql 4.0.0 or je suis en 3.23.43" que j'ai fait :heink: puis que je me suis rendu compte du déterrage :D


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed