¿Cómo unirse a la misma mesa varias veces?

9

Tengo dos tablas, "hierarchy_table" y "name_table".

La tabla de jerarquía contiene un objeto que tiene varios padres e hijos. Cada padre e hijo está referenciado por id.

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

Cada ID de objeto en la jerarquía_tabla tiene una entrada en la tabla_nombre:

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

¿Cómo unir cada ID en la jerarquía_tabla al nombre_tabla varias veces para que pueda tener un resultado donde se rellena cada nombre?

Me gusta esto:

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

Nota: los nombres de las tablas en el ejemplo son solo por claridad / simplicidad, los nombres reales tienen nombres propios.

jase81
fuente

Respuestas:

11

La hierarchy_tablecasa tiene 5 columnas que toda referencia al name_table, por lo que necesita 5 combinaciones. Puede ser mejor usar LEFTcombinaciones en lugar de INNER, en caso de que algunas de estas columnas sean anulables y aún desee que se devuelvan las filas:

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ᵀᴹ
fuente
Sí, entonces las columnas son anulables, así que necesito la combinación izquierda. Gracias.
jase81
Por alguna razón, no estaba entendiendo alias hasta esta respuesta. Vale la pena señalar que esto no funcionará en MS Access (tal vez otros). Estaba tratando de hacer algo muy similar y seguía recibiendo un error de sintaxis. El acceso requiere anidar uniones con ().
doubleJ
@doubleJ sí, Access es conocido por esta necesidad de paréntesis adicionales siempre que haya más de 1 uniones en el FROM.
ypercubeᵀᴹ
3

Puede usar el nombre de alias para las tablas involucradas en la consulta.

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
fuente
2
Será mejor que no uses las uniones de estilo antiguo (antiguo significa más de 20 años). La sintaxis ANSI es más legible y menos propensa a errores.
dezso
0

TL&DR: el alias se debe utilizar cuando desee unirse a la misma tabla varias veces

Racional:

En Postgres, normalmente las personas unen una columna en una tabla a otra columna en una tabla diferente. Esto fue brillante desde una perspectiva de diseño como el caso de uso normal. Cuando desee unir columnas adicionales, deberá usar alias (práctica recomendada).

CÓMO:

Al realizar una UNIÓN INTERNA, asegúrese de agregar una cláusula AS junto con el nombre.

Ejemplo

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

Si notas que la respuesta 'aceptada' hace esto arriba.

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
fuente