首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >SQL连接三个表,连接优先级

SQL连接三个表,连接优先级
EN

Stack Overflow用户
提问于 2010-09-23 23:56:50
回答 4查看 23.8K关注 0票数 29

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

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

代码语言:javascript
复制
SELECT
        *
    FROM 
        R
    JOIN    S ON (S.id = R.fks)

如果在S中没有记录,那么我就不会得到行,这是很好的。

则表S与P连接,其中记录为P,可能存在也可能不存在,并与S连接。

我就是这么做的

代码语言:javascript
复制
SELECT
        *
    FROM 
        R
    JOIN    S ON (S.id = R.fks)
    LEFT JOIN P ON (P.id = S.fkp)

如果我希望第二个连接绑定到S而不是R,比如我可以使用括号:

代码语言:javascript
复制
SELECT
        *
    FROM 
        R
    JOIN    (S ON (S.id = R.fks) JOIN P ON (P.id = S.fkp))

或者,这是笛卡尔乘积在R,S和P之间的一种自然行为吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-06-18 04:07:55

所有类型的外部连接和普通连接都在同一个优先级类中,并且运算符在查询的给定嵌套级别上从左到右生效。您可以将连接表达式放在右侧的圆括号中,以使其首先生效。请记住,您必须移动ON子句,以便它们与它们的连接保持一致-括号中的连接将其ON子句一起放入括号中,因此它现在文本上位于其他ON子句之前,后者将位于外部join语句中的括号之后。

(PostgreSQL示例)

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

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

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);

票数 52
EN

Stack Overflow用户

发布于 2010-09-24 00:11:59

连接第三个表时,您的第一个查询

代码语言:javascript
复制
SELECT
        *
    FROM 
        R
    JOIN    S ON (S.id = R.fks)

类似于您要连接到的第三个表的派生表。因此,如果R JOIN S没有生成任何行,那么连接P将永远不会生成任何行(因为您正在尝试连接到一个空表)。

因此,如果您正在寻找优先级规则,那么在本例中,它是使用LEFT JOIN而不是JOIN来设置的。

但是,我可能误解了您的问题,因为如果我编写查询,我会交换SR。例如:

代码语言:javascript
复制
SELECT
        *
    FROM 
        S
    JOIN    R ON (S.id = R.fks)
票数 3
EN

Stack Overflow用户

发布于 2010-09-24 00:03:06

第二个连接被绑定到S,因为您显式地声明了JOIN P ON (P.id = S.fkp) -在连接中没有引用来自R的列。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3780199

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档