Forum Programmation.SQL Implémentation d'une agrégation 0...1 et comptage des éléments agrégés

Posté par  .
Étiquettes : aucune
0
25
sept.
2009
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  . Évalué à 5.

    Bonjour,

    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
  • # Le requête à King-kong

    Posté par  . Évalué à 3.

    C'est ta requête qui ne va pas.

    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.