一尘不染

在一个查询中对多个表进行多个左联接

sql

我有一个master表,其中的项存储在多个级别(父母和孩子)中,还有另一个表,该表可能具有也可能没有其他数据。我需要从主表中查询两个级别,并在第二个表上具有左联接,但是由于查询中的排序这将无法工作。

SELECT something FROM master as parent, master as child
  LEFT JOIN second as parentdata ON parent.secondary_id = parentdata.id
  LEFT JOIN second as childdata ON child.secondary_id = childdata.id
WHERE parent.id = child.parent_id AND parent.parent_id = 'rootID'

左联接仅适用于from子句中的最后一个表,因此我只能使其对左联接之一起作用。在上面的示例中,所有左联接都不起作用,因为第一个左联接指向from子句中的第一个表,而第二个左联接则永远不会这样工作。

我该如何进行这项工作?


阅读 150

收藏
2021-03-17

共1个答案

一尘不染

这种查询应该可以工作-用显式JOIN语法重写后:

SELECT something
FROM   master      parent
JOIN   master      child ON child.parent_id = parent.id
LEFT   JOIN second parentdata ON parentdata.id = parent.secondary_id
LEFT   JOIN second childdata ON childdata.id = child.secondary_id
WHERE  parent.parent_id = 'rootID'

这里的绊脚石是JOIN在“旧样式”之前CROSS JOIN用逗号( ,
)显式绑定。我在这里引用手册:

无论如何,JOIN绑定都比逗号分隔列表FROM项更紧密 。

重写第一个之后,所有联接都从左到右应用(逻辑上-Postgres可以自由地在查询计划中重新排列表),并且可以正常工作。

只是为了说明我,这也行得通:

SELECT something
FROM   master parent
LEFT   JOIN second parentdata ON parentdata.id = parent.secondary_id
,      master child
LEFT   JOIN second childdata ON childdata.id = child.secondary_id
WHERE  child.parent_id = parent.id
AND    parent.parent_id = 'rootID'

但是,显式JOIN语法通常更可取,因为您的情况再次说明了这一点。

并且请注意,多个(LEFTJOIN可以将行相乘:

2021-03-17