146 votes

Comment inclure les résultats "zéro" / "0" dans l'agrégat COUNT ?

Je me suis juste retrouvé un peu coincé avec du SQL. Je ne pense pas pouvoir formuler la question brillamment - alors laissez-moi vous montrer.

J'ai deux tables, une appelée personne, une appelée rendez-vous. J'essaie d'obtenir le nombre de rendez-vous d'une personne (y compris si elle n'en a aucun). Rendez-vous contient le person_id et il y a un person_id par rendez-vous. Donc COUNT(person_id) est une approche raisonnable.

La requête :

SELECT person_id, COUNT(person_id) AS "number_of_appointments" 
FROM appointment 
GROUP BY person_id;

Retourne correctement le nombre de rendez-vous d'un person_id. Cependant, une personne qui n'a pas de rendez-vous n'est pas retournée (évidemment, car elle ne figure pas dans cette table).

En modifiant l'instruction pour prendre person_id dans la table person, j'obtiens quelque chose comme ça :

SELECT person.person_id, COUNT(appointment.person_id) AS "number_of_appointments"
FROM appointment
JOIN person ON person.person_id = appointment.person_id
GROUP BY person.person_id;

Cependant, cela ne retournera qu'un identifiant de personne qui a un rendez-vous et non ce que je veux, c'est-à-dire un retour avec des personnes qui n'ont pas de rendez-vous !

Des suggestions, s'il vous plaît ?

121voto

a_horse_with_no_name Points 100769

Vous avez besoin d'une jointure externe pour cela (et vous devez utiliser person comme table de "conduite").

SELECT person.person_id, COUNT(appointment.person_id) AS "number_of_appointments"
FROM person 
  LEFT JOIN appointment ON person.person_id = appointment.person_id
GROUP BY person.person_id;

La raison pour laquelle cela fonctionne, est que la jointure externe (gauche) retournera NULL pour les personnes qui n'ont pas de rendez-vous. La fonction agrégée count() ne comptera pas NULL et donc vous n'obtiendrez pas de zéro.

Si vous voulez en savoir plus sur les jointures extérieures, voici un bon tutoriel : http://sqlzoo.net/wiki/Using_Null

23voto

Hamlet Hakobyan Points 19023

Vous devez utiliser LEFT JOIN au lieu de INNER JOIN

SELECT person.person_id, COUNT(appointment.person_id) AS "number_of_appointments"
FROM person 
LEFT JOIN appointment ON person.person_id = appointment.person_id
GROUP BY person.person_id;

7voto

Francois Mazet Points 71

Si vous faites la jointure externe (avec le compte), puis utilisez ce résultat comme sous-table, vous pouvez obtenir 0 comme prévu (grâce à la fonction nvl).

Ex :

select P.person_id, nvl(A.nb_apptmts, 0) from 
(SELECT person.person_id
FROM person) P
LEFT JOIN 
(select person_id, count(*) as nb_apptmts
from appointment 
group by person_id) A
ON P.person_id = A.person_id

5voto

Rohini C.G Points 51

USE join pour obtenir 0 dans le résultat en utilisant GROUP BY.

simplement 'join' fait Inner join dans MS SQL donc, allez-y pour une jointure gauche ou droite.

Si la table qui contient la clé primaire est mentionnée en premier dans la requête, utilisez la jointure GAUCHE ou la jointure DROITE.

EG :

select WARDNO,count(WARDCODE) from MAIPADH 
right join  MSWARDH on MSWARDH.WARDNO= MAIPADH.WARDCODE
group by WARDNO

.

select WARDNO,count(WARDCODE) from MSWARDH
left join  MAIPADH on MSWARDH.WARDNO= MAIPADH.WARDCODE group by WARDNO

Prenez le groupe par de la table qui a la clé primaire et le compte de l'autre table qui a les entrées/détails réels.

4voto

sfj Points 107

Pour modifier encore moins votre requête originale, vous pouvez transformer votre jointure en une RIGHT rejoindre

SELECT person.person_id, COUNT(appointment.person_id) AS "number_of_appointments"
FROM appointment
RIGHT JOIN person ON person.person_id = appointment.person_id
GROUP BY person.person_id;

Cela s'appuie simplement sur la réponse sélectionnée, mais comme la jointure externe est dans la section RIGHT direction, il suffit d'ajouter un seul mot et moins de changements. - Rappelez-vous simplement qu'il existe et qu'il peut parfois rendre les requêtes plus lisibles et nécessiter moins de reconstruction.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X