Utilisation de la fonction COUNT() avec des valeurs NULL

Utilisation de la fonction COUNT() avec des valeurs NULL - SQL/NoSQL - Programmation

Marsh Posté le 14-06-2016 à 17:17:34    

Bonjour à tous,
 
Je m'excuse d'avance si certains trouvent la question idiote mais je n'arrive pas à solutionner ce problème, alors autant poser la question et apprendre.
 
Contexte :
J'ai une base de données avec 2 tables :
- une table reprenant des agents (ID_agt, nom, prénom)
- une table avec des supports (ID_sup, serialnumber, ID_agt)
 
Un agent est sensé n'avoir qu'un support mais dans le doute, je cherche à réaliser une requête qui renvoie :
- l'ensemble des agents (même ceux sans carte)
- avec un comptage du nombre de cartes qu'ils ont (0, 1, 2, ...)
 
Du coup, j'essaie ça :
 

Code :
  1. select distinct agent.nom, agent.prénom, count(support.ID_agt) from agent left join support on agent.ID = support.ID_agt group by support.ID_agt order by agent.nom;


 
Mon problème, c'est que dans la table des supports, un support  qui n'a pas été attribué a une valeur NULL dans la colonne ID_agt. Du coup, avec la requête ci-dessus, les agents qui n'ont pas de support attribué ne sortent pas.
 
J'ai donc essayé de remplacer la valeur NULL par une valeur 0 de la sorte :

Code :
  1. select distinct agent.nom, agent.prénom, count(case when support.ID_agt is null then 0 else 1 end) from agent left join support on agent.ID = support.ID_agt group by support.ID_agt order by agent.nom;


 
Nouveau problème: la valeur 0 étant un enregistrement, COUNT() la comptabilise. Et donc, tous mes agents sortent avec au minimum un support !!!
 
J'ai bien tenté de réaliser la même chose avec un SUM():

Code :
  1. select distinct agent.nom, agent.prénom, sum(case when support.ID_agt is null then 0 else 1 end) from agent left join support on agent.ID = support.ID_agt group by support.ID_agt order by agent.nom;


 
Mais j'ai dans ma base 16 agents différents qui ont le même nom et au final, la requête renvoie le nom et un comptage de 16 supports...
 
Bref, je ne m'en sors pas et un peu d'aide serait la bienvenue  :jap:  
 
Merci d'avance !

Reply

Marsh Posté le 14-06-2016 à 17:17:34   

Reply

Marsh Posté le 14-06-2016 à 20:08:06    

La solution plus simple serait d'utiliser isnull ou ifnull selon le sgbdr utilisé.
 
Mysql :

IFNULL(COUNT(*), 0)


---------------
On croit souvent avoir vu le fond de la stupidité humaine, et il parfois nécessaire qu'on vous rappelle qu'elle n'a pas de fond.
Reply

Marsh Posté le 15-06-2016 à 11:17:16    

Bonjour,
 
Merci pour ta réponse  :jap:  
 

bistouille a écrit :

La solution plus simple serait d'utiliser isnull ou ifnull selon le sgbdr utilisé.
 
Mysql :

IFNULL(COUNT(*), 0)



 
Du coup, ça ferait quelque chose dans ce goût là :
 

Code :
  1. select distinct agent.nom, agent.prénom, ifnull(count(support.ID_agt), 0) from agent left join support on agent.ID = support.ID_agt group by support.ID_agt order by agent.nom;


 
Et ... j'obtiens le même résultat, à savoir tous les agents à minima qui ont un support affecté, mais pas les agents sans support :(

Reply

Marsh Posté le 15-06-2016 à 11:34:31    

A mon avis si tu veux tous les agents (même sans carte) tu devrais plutôt faire un GROUP BY agent.ID_agt, pour la comptabilisation le SUM(CASE WHEN support.ID_agt IS NULL THEN 0 ELSE 1 END) devrait faire l'affaire...
 
Si tu n'y arrives, pas essayes de créer un http://sqlfiddle.com/ et nous pourrons essayer de corriger ta requête...


---------------
D3
Reply

Marsh Posté le 15-06-2016 à 15:30:07    

Super ça fonctionne !
 
J'ai ajouté l'ID dans la sélection pour y ajouter le GROUP BY et c'est peut-être juste ce champ qui manquait pour qu'il fasse bien le détail entre les agents.
 
Donc pour info, la requête finale qui fonctionne :
 

Code :
  1. select distinct agent.ID, agent.nom, agent.prénom, ifnull(count(support.ID_agt), 0) from agent left join support on agent.ID = support.ID_agt group by agent.ID order by agent.nom;


 
Merci bien  :jap:

Reply

Marsh Posté le 15-06-2016 à 15:48:27    

Pas sur que le DISTINCT agent.ID soit utile puisque on fait un GROUP BY agent.ID ! ^^


---------------
D3
Reply

Marsh Posté le 16-06-2016 à 00:51:24    

Je testerai, merci ;)

Reply

Sujets relatifs:

Leave a Replay

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