Comment rejoindre plusieurs fois la même table?

9

J'ai deux tables, "hierarchy_table" et "name_table".

La table de hiérarchie contient un objet qui a plusieurs parents et enfants. Chaque parent et enfant est référencé par id.

|  object_id  |  parent_id_1  |  parent_id_2  |  child_id_1  |  child_id_2  |
-----------------------------------------------------------------------------
|     1234    |      9999     |      9567     |     5555     |     5556     |
-----------------------------------------------------------------------------

Chaque ID d'objet dans la table hierarchy_table a une entrée dans la table name_table:

|  name_id  |    name    |
--------------------------
|   1234    |   ABCD     |
--------------------------
|   9999    |   ZYXW     |
--------------------------
| ...

Comment joindre plusieurs fois chaque identifiant de la hierarchy_table à la name_table afin d'avoir un résultat où chaque nom est rempli?

Comme ça:

|   object    |   parent_1    |   parent_2    |   child_1    |   child_2    |
-----------------------------------------------------------------------------
|     ABCD    |      ZYXW     |      BBBB     |     CCCC     |     DDDD     |
-----------------------------------------------------------------------------

Remarque: les noms de table dans l'exemple sont juste pour la clarté / simplicité, les vrais noms ont des noms propres.

jase81
la source

Réponses:

11

Le hierarchy_tablea 5 colonnes qui font toutes référence au name_table, vous avez donc besoin de 5 jointures. Il peut être préférable d'utiliser des LEFTjointures au lieu de INNER, dans le cas où certaines de ces colonnes peuvent être annulées et que vous souhaitez toujours que les lignes soient renvoyées:

SELECT 
    o.name  AS object, 
    p1.name AS parent_1, 
    p2.name AS parent_2, 
    c1.name AS child_1,  
    c2.name AS child_2 
FROM 
    hierarchy_table AS h
  LEFT JOIN name_table AS o   ON h.object_id   = o.name_id
  LEFT JOIN name_table AS p1  ON h.parent_id_1 = p1.name_id  
  LEFT JOIN name_table AS p2  ON h.parent_id_2 = p2.name_id
  LEFT JOIN name_table AS c1  ON h.child_id_1  = c1.name_id 
  LEFT JOIN name_table AS c2  ON h.child_id_2  = c2.name_id ;
ypercubeᵀᴹ
la source
Oui, les colonnes peuvent donc être annulées, j'ai donc besoin de la jointure gauche. Je vous remercie.
jase81
Pour une raison quelconque, je ne comprenais pas l'alias jusqu'à cette réponse. Il convient de noter que cela ne fonctionnera pas dans MS Access (peut-être d'autres). J'essayais de faire quelque chose de très similaire et j'ai toujours eu une erreur de syntaxe. L'accès nécessite l'imbrication des jointures avec ().
doubleJ
@doubleJ oui, Access est connu pour ce besoin de parenthèses supplémentaires chaque fois qu'il y a plus de 1 jointures dans le FROM.
ypercubeᵀᴹ
3

Vous pouvez utiliser un nom d'alias pour les tables impliquées dans la requête.

select b.name object, c.name parent_1, d.name parent_2 
from hierarchy_table a, name_table b, name_table c, name_table d
where a.object_id = b.name_id 
  and a.parent_id_1 = c.name_id 
  and a.parent_id_2 = d.name_id
Isaac A. Nugroho
la source
2
Vous feriez mieux de ne pas utiliser les jointures à l'ancienne (ancien signifie plus de 20 ans). La syntaxe ANSI est plus lisible et moins sujette aux erreurs.
dezso
0

TL&DR: l' alias doit être utilisé lorsque vous souhaitez vous connecter plusieurs fois à la même table

Rationnel:

Dans Postgres, les gens joignent généralement une colonne d'une table à une autre colonne d'une table différente. C'était génial du point de vue de la conception comme cas d'utilisation normal. Lorsque vous souhaitez joindre des colonnes supplémentaires, vous devrez utiliser des alias (meilleure pratique).

COMMENT:

Lorsque vous effectuez une INNER JOIN, assurez-vous d'ajouter une clause AS avec le nom.

Exemple

INNER JOIN ipaddresses as child_address ON ipaddress_relations.ipaddress_id = child_address.ipaddressid

Si vous remarquez la réponse «acceptée», procédez comme ci-dessus.

SELECT 
    o.name  AS object, 
    p1.name AS parent_1, 
    p2.name AS parent_2, 
    c1.name AS child_1,  
    c2.name AS child_2 
FROM 
    hierarchy_table AS h
  LEFT JOIN name_table AS o   ON h.object_id   = o.name_id
  LEFT JOIN name_table AS p1  ON h.parent_id_1 = p1.name_id  
  LEFT JOIN name_table AS p2  ON h.parent_id_2 = p2.name_id
  LEFT JOIN name_table AS c1  ON h.child_id_1  = c1.name_id 
  LEFT JOIN name_table AS c2  ON h.child_id_2  = c2.name_id ;
FlyingV
la source