连接语句操作顺序
Posted
技术标签:
【中文标题】连接语句操作顺序【英文标题】:Join statement order of operation 【发布时间】:2012-09-21 06:45:47 【问题描述】:给定以下3种方式加入
select t1.* from t1
left join t2 on t1.fk = t2.pk
join t3 on t2.fk = t3.pk
如果 t2 和 t3 之间的连接失败,是否会返回 t1 和 t2 之间连接成功的行?如果操作顺序是从左到右,我假设不是,但是如果它是从右到左计算的(t3 先连接到 t2),那么即使前者失败,t1 仍然会返回。
它是如何工作的?
【问题讨论】:
【参考方案1】:ON
子句的位置控制评估的逻辑顺序。
所以首先发生t1 LEFT JOIN t2 ON t1.fk = t2.pk
。此连接的结果是一个虚拟表,其中包含来自t1, t2
的所有匹配行,并且(因为它是左外连接)任何不匹配的t1
行也将保留为t2
列的空值。
然后这个虚拟表参与下一个连接。 JOIN t3 ON t2.fk = t3.pk
任何与t1
中的行不匹配的t2
记录都不是第一阶段的虚拟表输出的一部分,因此不会出现在最终结果中。此外,t2.fk = t3.pk
上的此内部联接将丢失 t2.fk
的任何 NULL
值,从而有效地将您的整个事物重新转换为内部联接。
逻辑查询处理很好解释by Itzik Ben Gan here
【讨论】:
回答的重点,讲解的很全面。感谢您的帮助。 很好很简单的解释我想知道相同的操作顺序是否适用于sqlite
?
@MuhammadBabar - 我没有使用过 SQLLite,但如果它符合标准 (ANSI/ISO) SQL,它会。
希望它坚持。好的,如果我将上述查询修改为select t1.* from t1 inner join t2 on t1.fk = t2.pk left join t3 on **t1.fk** = t3.pk
会发生什么
@MuhammadBabar - 第一部分是。第二个连接将应用于从第一个连接获得的虚拟表。拒绝第二部分,因为没有任何东西可以保证 t2.fk 和 t1.fk 的值相同,因此查询可能返回不同的结果,但这不会改变逻辑描述。以上是关于连接语句操作顺序的主要内容,如果未能解决你的问题,请参考以下文章
sql语句--添加数据--修改语句--删除语句---连接查询