Como ingressar na mesma tabela várias vezes?

9

Eu tenho duas tabelas, "hierarchy_table" e "name_table".

A tabela de hierarquia contém um objeto que possui vários pais e filhos. Cada pai e filho são referenciados 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 na tabela hierarchy_ possui uma entrada na tabela name_table:

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

Como associo cada ID na tabela hierarchy_table à tabela name_table várias vezes para que eu possa ter um resultado em que todos os nomes sejam preenchidos?

Como isso:

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

Nota: os nomes das tabelas no exemplo são apenas para maior clareza / simplicidade, os nomes reais têm nomes próprios.

jase81
fonte

Respostas:

11

O hierarchy_tablepossui 5 colunas que referenciam o name_table, então você precisa de 5 junções. Pode ser melhor usar LEFTjunções em vez de INNER, caso algumas dessas colunas sejam anuláveis ​​e você ainda queira que as linhas sejam retornadas:

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ᵀᴹ
fonte
Sim, então as colunas são anuláveis, então eu preciso da junção esquerda. Obrigado.
jase81
Por alguma razão, eu não estava conseguindo entender o alias até esta resposta. Pode ser interessante notar que isso não funcionará no MS Access (talvez outros). Eu estava tentando fazer algo muito semelhante e continuava recebendo um erro de sintaxe. O acesso requer o aninhamento de Joins com ().
doubleJ
@doubleJ sim, o Access é notório por essa necessidade de parênteses extras sempre que houver mais de 1 junção no FROM.
ypercubeᵀᴹ
3

Você pode usar o nome alternativo para tabelas envolvidas na 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
fonte
2
É melhor não usar as junções de estilo antigo (idade significa mais de 20 anos). A sintaxe ANSI é mais legível e menos suscetível a erros.
Dez27
0

TL&DR: Alias ​​deve ser usado quando você deseja ingressar na mesma tabela várias vezes

Racional:

No Postgres, normalmente as pessoas associam uma coluna em uma tabela a outra coluna em uma tabela diferente. Isso foi brilhante da perspectiva do design, como o caso de uso normal. Quando você quiser ingressar em colunas adicionais, precisará usar aliases (prática recomendada).

COMO:

Ao executar uma INNER JOIN, adicione uma cláusula AS junto com o nome.

Exemplo

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

Se você perceber que a resposta 'aceita' faz isso acima.

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
fonte