Bonjour,
cela fait plusieurs fois que je suis confronté à ce problème, sans savoir comment le résoudre.
Je dispose de deux entités, par exemple user et group, telles qu'un utilisateur peut appartenir à 0 ou 1 groupe.
En UML, je crois qu'on appelle cela une agrégation de cardinalité 0...1.
Côté base de données, j'implémente cette relation par l'ajout d'une clé étrangère group_id dans la table user, qui vaut NULL dans le cas où l'utilisateur n'appartient pas à un groupe.
Je voudrais savoir si cette implémentation est correcte.
En effet, avec une telle implémentation, je bloque sur une requête.
Je veux connaître le nombre d'utilisateurs de chaque groupe.
Pour cela, j'effectue cette requête :
SELECT group.name, COUNT(user.id) FROM group, user WHERE user.group_id = group.id GROUP BY user.group_id
J'obtiens alors un tableau associatif de la forme :
groupe1: 5
groupe2; 3
groupe3: 8
...
Mon problème est que si un groupe ne contient pas d'utilisateur, il ne figure pas dans mon tableau.
Or, si le cas se présente, je veux que le tableau contienne tout simplement une ligne :
groupeN: 0
Est-ce mon implémentation de l'agrégation, ou bien ma requête, qui est inapropriée ?
Merci d'avance pour vos conseils.
# Jointure externe
Posté par ctetruite . Évalué à 5.
Ton implémentation est bonne si un utilisateur ne peut appartenir qu'à un seul groupe au maximum. Par contre, ta requête doit prendre en compte tous les groupes, même ceux non présents dans la table des utilisateurs. Donc jointure externe du côté de la table des groupes :
SELECT group.name, COUNT(user.id) FROM group LEFT OUTER JOIN user ON user.group_id=group.id GROUP BY group.id;
Ca donne qqch du genre
+--------+------------------+
| name | count(user.id) |
+--------+------------------+
| group1 | 2 |
| group2 | 2 |
| group3 | 0 |
| group4 | 0 |
| group5 | 0 |
+--------+------------------+
Cdt
[^] # Re: Jointure externe
Posté par santos . Évalué à 3.
Je vais étudier de plus près les jointures SQL. Mes connaissances sont limités dans ce domaine.
[^] # Re: Jointure externe
Posté par David FRANCOIS (site web personnel) . Évalué à 1.
# Le requête à King-kong
Posté par Kerro . Évalué à 3.
D'abord, avis perso, faire une jointure implicite, pabô. D'autres ont d'autres avis sur la question, mais une jointure explicite (inner join bien souvent) permet de clarifier les choses.
"user.group_id = group.id" va toujours sauter le cas où tu as NULL.
Ajoutes simplement un "union" pour "SELECT "NULL", COUNT(id) FROM user WHERE group_id=NULL" ou quelque chose du genre.
Sinon ça fonctionne tout seul avec la bonne jointure, et c'est plus classe :-)
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.