如何多次连接到同一张表?


9

我有两个表,“ hierarchy_table”和“ name_table”。

层次结构表包含一个具有多个父级和子级的对象。每个父母和孩子都由id引用。

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

等级表中的每个对象ID在名称表中都有一个条目:

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

如何将hierarchy_table中的每个ID多次连接到name_table,以便可以得到填充每个名称的结果?

像这样:

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

注意:示例中的表名只是为了清楚/简单起见,真实名称具有专有名称。

Answers:


11

hierarchy_table5列均引用name_table,因此您需要5个联接。如果其中某些列可为空并且您仍然希望返回行,则最好使用LEFTjoin而不是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 ;

是的,所以列是可为空的,所以我确实需要左连接。谢谢。
jase81 '16

由于某种原因,直到得到这个答案,我才对别名有所了解。可能值得注意的是,这在MS Access(也许其他)中不起作用。我试图做一些非常相似的事情,但不断出现语法错误。访问要求嵌套带有()的Joins。
doubleJ

@doubleJ是的,只要在中有1个以上的连接,Access都会因为需要额外的括号而臭名昭著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语法更具可读性,并且不易出错。
dezso

0

TL&DR:当您想多次连接到同一张表时,应使用别名

合理的:

在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 ;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.