web-dev-qa-db-fra.com

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

Je viens de me retrouver un peu coincé avec du SQL. Je ne pense pas que je puisse formuler la question avec brio - alors laissez-moi vous montrer.

J'ai deux tables, une personne appelée et une autre sur rendez-vous. J'essaie de renvoyer le nombre de rendez-vous qu'une personne a (y compris s'ils ont zéro). Le rendez-vous contient le person_id et il y a un person_id par rendez-vous. Donc, COUNT(person_id) est une approche sensée.

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 qu'une personne_id a. Cependant, une personne qui a 0 rendez-vous n'est pas renvoyée (évidemment, car ils ne sont pas dans ce tableau).

Modifier la déclaration pour prendre person_id de la table personne me donne quelque chose comme:

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 renverra toujours qu'une personne_id qui a un rendez-vous et non ce que je veux, qui est un retour avec des personnes qui ont 0 rendez-vous!

Des suggestions s'il vous plaît?

99
BrownE

Vous voulez une jointure externe pour cela (et vous devez utiliser la personne 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) renverra NULL pour les personnes qui n'ont pas de rendez-vous. La fonction d'agrégation count() ne comptera pas les valeurs NULL et vous obtiendrez ainsi un zéro.

Si vous voulez en savoir plus sur les jointures externes, voici un tutoriel de Nice: http://sqlzoo.net/wiki/Using_Null

88

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;
21
Hamlet Hakobyan

si vous faites la jointure externe (avec le nombre), 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
7
Francois Mazet

Utilisez la jointure pour obtenir un compte 0 dans le résultat à l'aide de GROUP BY.

simplement 'rejoindre' Inner rejoint-il dans MS SQL alors, optez pour une jointure gauche ou droite.

Si la table contenant la clé primaire est mentionnée en premier dans la requête QUERY, utilisez la jointure LEFT, sinon la jointure RIGHT.

PAR EXEMPLE:

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 group by dans la table qui a la clé primaire et comptez dans une autre table qui contient les entrées/détails.

5
Rohini C.G

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

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 ne fait que s'appuyer sur la réponse sélectionnée, mais comme la jointure externe se trouve dans la direction RIGHT, il ne faut ajouter qu'un seul mot et moins de modifications. - Rappelez-vous qu’il est là et peut parfois rendre les requêtes plus lisibles et demander moins de reconstruction.

2
sfj