连接顺序在SQL中是否重要?

Jus*_*ner 173 sql join relational-database

无视性能,我会从下面的查询A和B得到相同的结果吗?C和D怎么样?

-- A
select *
from   a left join b
           on <blahblah>
       left join c
           on <blahblan>


-- B
select *
from   a left join c
           on <blahblah>
       left join b
           on <blahblan>  

-- C
select *
from   a join b
           on <blahblah>
       join c
           on <blahblan>


-- D
select *
from   a join c
           on <blahblah>
       join b
           on <blahblan>  
Run Code Online (Sandbox Code Playgroud)

ype*_*eᵀᴹ 210

对于INNER连接,不,顺序无关紧要.该查询将返回相同的结果,只要你改变你的选择SELECT *SELECT a.*, b.*, c.*.


对于(LEFT,RIGHTFULL)OUTER连接,是的,顺序很重要 - 而且(更新的)事情要复杂得多.

首先,外连接不是可交换的,所以a LEFT JOIN b不一样b LEFT JOIN a

外连接也不是关联的,因此在您的示例中涉及(交换性和关联性)属性:

a LEFT JOIN b 
    ON b.ab_id = a.ab_id
  LEFT JOIN c
    ON c.ac_id = a.ac_id
Run Code Online (Sandbox Code Playgroud)

相当于:

a LEFT JOIN c 
    ON c.ac_id = a.ac_id
  LEFT JOIN b
    ON b.ab_id = a.ab_id
Run Code Online (Sandbox Code Playgroud)

但:

a LEFT JOIN b 
    ON  b.ab_id = a.ab_id
  LEFT JOIN c
    ON  c.ac_id = a.ac_id
    AND c.bc_id = b.bc_id
Run Code Online (Sandbox Code Playgroud)

不等于:

a LEFT JOIN c 
    ON  c.ac_id = a.ac_id
  LEFT JOIN b
    ON  b.ab_id = a.ab_id
    AND b.bc_id = c.bc_id
Run Code Online (Sandbox Code Playgroud)

另一个(希望更简单)相关性的例子.把它想象成(a LEFT JOIN b) LEFT JOIN c:

a LEFT JOIN b 
    ON b.ab_id = a.ab_id          -- AB condition
 LEFT JOIN c
    ON c.bc_id = b.bc_id          -- BC condition
Run Code Online (Sandbox Code Playgroud)

等同a LEFT JOIN (b LEFT JOIN c):

a LEFT JOIN  
    b LEFT JOIN c
        ON c.bc_id = b.bc_id          -- BC condition
    ON b.ab_id = a.ab_id          -- AB condition
Run Code Online (Sandbox Code Playgroud)

只是因为我们有"好"的ON条件.这两个ON b.ab_id = a.ab_idc.bc_id = b.bc_id是平等的检查,不涉及NULL比较.

您甚至可以与其他运营商或更复杂的运营商有条件,例如:ON a.x <= b.xON a.x = 7ON a.x LIKE b.xON (a.x, a.y) = (b.x, b.y)两个查询仍然是等效的.

但是,如果涉及任何这些IS NULL或与null相关的函数,COALESCE()例如条件是b.ab_id IS NULL,那么这两个查询将不相等.

  • 如果外连接是关联的,只要一个表中的所有列都为NULL,而不是说只要谓词不涉及IS NULL或者它是关联的,那么外连接就是关联的. '与空值相关的函数'.人们可以很容易地想象出一个满足前一个描述而不是后一个描述的谓词,比如`a.somecol> 0 OR b.someothercol> 0`; 关联性可能会因此而失败. (3认同)
  • @MarkAmery谢谢你,我很难在这一点上构建我的句子(而且我已经对你的答案投了赞成票;) (2认同)

Teo*_* J. 13

如果您在加入 B 之前尝试在 B 的字段上加入 C,即:

SELECT A.x, 
       A.y, 
       A.z 
FROM A 
   INNER JOIN C
       on B.x = C.x
   INNER JOIN B
       on A.x = B.x
Run Code Online (Sandbox Code Playgroud)

您的查询将失败,因此在这种情况下顺序很重要。


Die*_*ego 5

对于常规连接,它没有。TableA join TableB将产生相同的执行计划TableB join TableA(因此您的 C 和 D 示例将相同)

对于左右连接,它确实如此。TableA left Join TableB与 不同TableB left Join TableA,但与TableB right Join TableA

  • 这仅解决了可交换性,但问题中的示例表明提问者对结合性感兴趣。ypercube 的回答同时解决了这两个问题。 (4认同)