SQL - 这些连接之间的区别?

时间:2009-07-07 20:10:49

标签: sql sql-server database tsql join

我现在应该知道这一点,但是,如果下面两个陈述之间有什么区别呢?

嵌套连接:

SELECT
    t1.*
FROM
    table1 t1
    INNER JOIN table2 t2
        LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID
    ON t2.table2_ID = t1.table1_ID

更传统的加入:

SELECT
    t1.*
FROM
    table1 t1
    INNER JOIN table2 t2 ON t2.table2_ID = t1.table1_ID
    LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID

4 个答案:

答案 0 :(得分:5)

嗯,这是操作的顺序..

SELECT
    t1.*
FROM
    table1 t1
    INNER JOIN table2 t2
        LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID
    ON t2.table2_ID = t1.table1_ID

可以改写为:

SELECT
    t1.*
FROM
       table1 t1                                                       -- inner join t1
    INNER JOIN 
       (table2 t2 LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID)  -- with this 
    ON t2.table2_ID = t1.table1_ID                                     -- on this condition

所以基本上,首先你根据连接条件LE3 JOIN t2,基于连接条件:table3_ID = table2_ID,然后INNER JOIN t1,t2 on table2_ID = table1_ID。

在你的第二个例子中,你首先用t2 INNER JOIN t1,然后在条件table2_ID = table1_ID上用表t3 LEFT JOIN得到的内连接。

SELECT
    t1.*
FROM
    table1 t1
    INNER JOIN table2 t2 ON t2.table2_ID = t1.table1_ID
    LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID        

可以改写为:

SELECT
    t1.*
FROM
        (table1 t1 INNER JOIN table2 t2 ON t2.table2_ID = t1.table1_ID) -- first inner join
    LEFT JOIN                                                           -- then left join
        table3 t3 ON t3.table3_ID = t2.table2_ID                        -- the result with this

修改

我道歉。我的第一句话是错的。这两个查询将产生相同的结果,但性能可能有所不同,因为在某些情况下第一个查询的执行速度可能比第二个查询慢(当表1仅包含表2中元素的子集时),因为LEFT JOIN将首先执行 - 然后才与table1相交。与允许查询优化器完成它的第二个查询相反。

答案 1 :(得分:4)

对于您的具体示例,我认为生成的查询计划不应该有任何差异,但可读性肯定存在差异。你的第二个例子很容易理解。

如果您要反转示例中的连接类型,最终可能会得到很多不同的结果。

SELECT    t1.*
FROM    table1 t1
    LEFT JOIN table2 t2 ON t2.table2_ID = t1.table1_ID
    INNER JOIN table3 t3 ON t3.table3_ID = t2.table2_ID

-- may not produce the same results as...

SELECT    t1.*
FROM    table1 t1
    LEFT JOIN table2 t2
        INNER JOIN table3 t3 ON t3.table3_ID = t2.table2_ID
    ON t2.table2_ID = t1.table1_ID

基于连接顺序在很多情况下很重要的事实 - 仔细考虑应该如何编写连接语法。如果您发现第二个示例是您真正想要完成的,我会考虑重写查询,以便您可以更加强调连接的顺序......

SELECT    t1.*
FROM    table2 t2
        INNER JOIN table3 t3 ON t3.table3_ID = t2.table2_ID
        RIGHT JOIN table1 t1 ON t2.table2_ID = t1.table1_ID

答案 2 :(得分:2)

查看这两个查询的不同之处的最佳方法是比较这两个查询的查询计划。

这些 IF 的结果集没有区别。在table3中,table2中的给定行总是有行。

我在我的数据库上尝试了它,查询计划的不同之处在于 1.对于第一个查询,优化器首先选择在table2和表3上进行连接。 2.对于第二个查询,优化器首先选择连接table1和table2。

答案 3 :(得分:0)

如果您的DBMS优化器达到最佳状态,您应该看到两个查询之间没有任何区别。然而,即使对于大型的高成本平台而言,这并不是我有信心做出的假设,所以我发现查询计划(以及执行时间)各不相同,我也不会感到惊讶。