Come aderire alla stessa tabella più volte?


9

Ho due tabelle, "hierarchy_table" e "name_table".

La tabella gerarchica contiene un oggetto con più genitori e figli. Ogni genitore e figlio è indicato da id.

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

Ogni ID oggetto in hierarchy_table ha una voce in name_table:

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

Come posso unire ogni ID in hierarchy_table a name_table più volte in modo da poter avere un risultato in cui ogni nome è popolato?

Come questo:

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

Nota: i nomi delle tabelle nell'esempio sono solo per chiarezza / semplicità, i nomi reali hanno nomi propri.

Risposte:


11

L' hierarchy_tableha 5 colonne che ogni riferimento la name_table, quindi è necessario 5 join. Potrebbe essere meglio utilizzare i LEFTjoin anziché INNER, nel caso in cui alcune di queste colonne siano nullable e si desideri comunque restituire le righe:

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 ;

Sì, quindi le colonne sono nullable, quindi ho bisogno del join sinistro. Grazie.
jase81,

Per qualche ragione, non stavo ottenendo una comprensione dell'aliasing fino a questa risposta. Vale la pena notare che questo non funzionerà in MS Access (forse altri). Stavo cercando di fare qualcosa di molto simile e continuavo a ricevere un errore di sintassi. L'accesso richiede l'annidamento di Joins con ().
doubleJ,

@doubleJ Sì, Access è noto per questa necessità di parentesi extra ogni volta che ci sono più di 1 join in FROM.
ypercubeᵀᴹ

3

È possibile utilizzare il nome alias per le tabelle coinvolte nella query.

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

2
Faresti meglio a non usare i join vecchio stile (vecchio significa più di 20 anni). La sintassi ANSI è più leggibile e meno soggetta a errori.
dezso

0

TL&DR: Alias ​​dovrebbe essere usato quando vuoi unirti alla stessa tabella più volte

Razionale:

In Postgres, in genere le persone uniscono una colonna in una tabella a un'altra colonna in una tabella diversa. Questo è stato brillante dal punto di vista del design come il normale caso d'uso. Quando vuoi unire altre colonne dovrai usare gli alias (best practice).

COME:

Quando si esegue un INNER JOIN, assicurarsi di aggiungere una clausola AS insieme al nome.

Esempio

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

Se noti che la risposta "accettata" lo fa sopra.

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 ;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.