34

我有一张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 子句中的第一个表,第二个永远不会像这样工作。

我怎样才能使这项工作?

4

3 回答 3

51

这种查询应该可以工作 - 在用显式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-list 项的逗号更紧密。

在重写第一个之后,所有连接都是从左到右应用的(逻辑上 - 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,正如您的案例再次说明的那样,显式语法通常更可取。

并注意 multiple ( LEFT)JOIN可以乘以行:

于 2013-01-10T15:15:10.013 回答
7

You can do like this

SELECT something
FROM
    (a LEFT JOIN b ON a.a_id = b.b_id) LEFT JOIN c on a.a_aid = c.c_id
WHERE a.parent_id = 'rootID'
于 2015-04-29T14:07:36.737 回答
3

这些JOIN语句也是FROM子句的一部分,更正式地说, join_type用于将两个from_item组合成一个from_item,其中多个可以在FROM. 请参阅http://www.postgresql.org/docs/9.1/static/sql-select.html

因此,您的问题的直接解决方案是:

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

JOIN正如已经建议的那样,更好的选择是只使用's。

于 2013-01-10T15:35:18.600 回答