admin

SQL联接三个表,联接优先

sql

我有三个表:R,S和P。

表R通过外键与S连接;有 应该 是S中至少一个的记录,所以我可以加入:

SELECT
        *
    FROM 
        R
    JOIN    S ON (S.id = R.fks)

如果S中没有记录,那么我没有行,那很好。

然后表S与P联接,其中记录为P可能存在,也可能不存在,并与S联接。

所以我做

SELECT
        *
    FROM 
        R
    JOIN    S ON (S.id = R.fks)
    LEFT JOIN P ON (P.id = S.fkp)

如果我想将第二个JOIN绑定到S而不是R,例如我可以使用括号,该怎么办:

SELECT
        *
    FROM 
        R
    JOIN    (S ON (S.id = R.fks) JOIN P ON (P.id = S.fkp))

还是这已经是R,S和P之间笛卡尔积的自然行为?


阅读 191

收藏
2021-05-10

共1个答案

admin

各种外部联接和普通联接都在相同的优先级类中,并且运算符在给定的查询嵌套级别从左到右生效。您可以将连接表达式放在括号的右侧,以使其首先生效。请记住,您必须四处移动这些ON子句,以使它们与连接保持在一起-“括号中的join将其ON子句与之一起放入括号中,因此,现在它在文字上先于另一个ON子句,该子句将在括号之后。

(PostgreSQL示例)

SELECT * FROM a LEFT JOIN b ON (a.id = b.id) JOIN c ON (b.ref = c.id);

ab连接首先生效,但是我们可以通过将bc连接放在括号中来强制bc连接首先生效,如下所示:

SELECT * FROM a LEFT JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);

通常,您可以通过移动连接并更改外部连接的方向来表达相同的内容而没有多余的括号,例如

SELECT * FROM b JOIN c ON (b.ref = c.id) RIGHT JOIN a ON (a.id = b.id);

2021-05-10