Как присоединиться к одной и той же таблице несколько раз?

9

У меня есть две таблицы: «имя_Иерархии» и «имя_таблицы».

Таблица иерархии содержит объект, который имеет несколько родителей и потомков. На каждого родителя и ребенка ссылается идентификатор.

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

У каждого идентификатора объекта вierarchy_table есть запись в name_table:

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

Как мне объединить каждый идентификатор в иерархической таблице с таблицей имен несколько раз, чтобы получить результат, где каждое имя заполнено?

Нравится:

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

Примечание: имена таблиц в примере приведены только для ясности / простоты, настоящие имена имеют собственные имена.

jase81
источник

Ответы:

11

hierarchy_tableИмеет 5 колонок , что все ссылки name_table, так что вам нужно 5 соединений. Может быть лучше использовать LEFTобъединения вместо INNER, если некоторые из этих столбцов обнуляются и вы все еще хотите, чтобы строки возвращались:

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ᵀᴹ
источник
Да, поэтому столбцы обнуляются, поэтому мне нужно левое соединение. Спасибо.
jase81
По какой-то причине я просто не мог понять псевдонимы до этого ответа. Возможно, стоит отметить, что это не будет работать в MS Access (может быть, другие). Я пытался сделать что-то очень похожее и получал синтаксическую ошибку. Для доступа требуется вложение соединений с ().
doubleJ
@doubleJ да, Access печально известен необходимостью использования дополнительных скобок, если в них более 1 объединения FROM.
ypercubeᵀᴹ
3

Вы можете использовать псевдоним для таблиц, участвующих в запросе.

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
Не стоит использовать соединения в старом стиле (старые означает более 20 лет). Синтаксис ANSI более читабелен и менее подвержен ошибкам.
Дезсо
0

TL & DR: псевдоним следует использовать, если вы хотите присоединиться к одной и той же таблице несколько раз

Rational:

В Postgres обычно люди объединяют один столбец в одной таблице с другим столбцом в другой таблице. Это было блестяще с точки зрения дизайна в качестве обычного варианта использования. Если вы хотите присоединиться к дополнительным столбцам, вам нужно использовать псевдонимы (наилучшая практика).

КАК:

При выполнении INNER JOIN обязательно добавьте предложение AS вместе с именем.

пример

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

Если вы заметили «принятый» ответ, сделайте это выше.

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
источник