微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sql-server – SQL ANSI JOIN优先级

我有一个看起来像这样的查询

    SELECT *
      FROM TBLA A
 LEFT JOIN TBLB B ON A.Col1 = B.Col2
RIGHT JOIN TBLC C ON B.Col3 = C.Col4
      JOIN TBLD D ON C.Col5 = D.Col6

联接以哪种顺序解决?我对sql Server最感兴趣,并将其作为答案标记为解释,但我对ANSI / ISO标准及其在各种RDBMS中的工作方式同样感兴趣.

这个问题的原因是要找出结果与此查询不同的原因

    SELECT *
      FROM TBLA A
CROSS JOIN TBLC C
 LEFT JOIN TBLB B ON A.Col1 = B.Col2 AND B.Col3 = C.Col4
      JOIN TBLD D ON C.Col5 = D.Col6

解决方法:

从逻辑上讲,连接按照从左到右的ON子句的顺序进行解析.

每个连接的输出是进入下一个连接的虚拟表.

因此,对于您的问题中的查询,A LJ B的虚拟表结果然后正确地连接到C.BolCol3 = C.Col4的连接条件将丢失由原始左连接保留的任何空扩展行有效地转换第一连接返回到内连接,然后生成的虚拟表(保留C中的所有行)内部连接到D.

因此,您的初始查询可以简化为

SELECT *
FROM TBLA A
INNER JOIN TBLB B ON A.Col1 = B.Col2
RIGHT JOIN TBLC C ON B.Col3 = C.Col4
      JOIN TBLD D ON C.Col5 = D.Col6

这与(A IJ B)ROJ(C IJ D)实际上相同

ON子句的顺序不一定与表在查询中出现的顺序相同.这也可以改写为(C IJ D)LOJ(A IJ B)

SELECT *
FROM   TBLC C
       INNER JOIN TBLD D
         ON C.Col5 = D.Col6
       LEFT JOIN TBLA A
                 INNER JOIN TBLB B
                   ON A.Col1 = B.Col2
         ON B.Col3 = C.Col4 

on子句的位置意味着外连接是在(C IJ D)和(A IJ B)而不是仅在单个表上产生的两个虚拟表之间执行的.

在概念上,在第二个查询中,虚拟表A x C保持连接到B上,保留整个笛卡尔积,然后将其结果与谓词C.Col5 = D.Col6连接到D上.这消除了最终结果中没有C和D之间内部连接的任何行,这意味着它等效于

SELECT *
FROM   TBLC C
       JOIN TBLD D
         ON C.Col5 = D.Col6
       CROSS JOIN TBLA A
       LEFT JOIN TBLB B
         ON A.Col1 = B.Col2
            AND B.Col3 = C.Col4 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐