web-dev-qa-db-fra.com

Comment rejoindre plusieurs fois la même table?

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 plus de clarté/simplicité, les vrais noms ont des noms propres.

9
jase81

Le hierarchy_table possède 5 colonnes qui font toutes référence à name_table, vous avez donc besoin de 5 jointures. Il peut être préférable d'utiliser LEFT jointures 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 ;
11
ypercubeᵀᴹ

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
3
Isaac A. Nugroho

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).

HOWTO:

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 ;
0
FlyingV