忽略性能,我将从下面的查询A和B得到相同的结果吗?C和D呢?

----- Scenario 1: 
-- A (left join)
select *
from   a left join b
           on <blahblah>
       left join c
           on <blahblan>


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

----- Scenario 2:   
-- C (inner join)
select *
from   a join b
           on <blahblah>
       join c
           on <blahblan>


-- D (inner join)
select *
from   a join c
           on <blahblah>
       join b
           on <blahblan>  

当前回答

对于INNER连接,不,顺序不重要。查询将返回相同的结果,只要您将SELECT *改为SELECT a.*, b.*, c.*。


对于(LEFT, RIGHT或FULL) 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

等价于:

a LEFT JOIN c 
    ON c.ac_id = a.ac_id
  LEFT JOIN b
    ON b.ab_id = a.ab_id

but:

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

不等于:

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

另一个(希望更简单)结合性的例子。可以把它想成(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

这相当于一个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

只是因为我们有“不错”的ON条件。ON b.ab_id = a.ab_id和c.bc_id = b.bc_id都是相等性检查,不涉及NULL比较。

您甚至可以使用其他操作符或更复杂的操作符设置条件,如:ON a.x <= b.x或ON a.x = 7或ON a.x like b.x或ON (a.x, a.y) = (b.x, b.y),这两个查询仍然是等效的。

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

其他回答

Oracle optimizer chooses join order of tables for inner join. Optimizer chooses the join order of tables only in simple FROM clauses . U can check the oracle documentation in their website. And for the left, right outer join the most voted answer is right. The optimizer chooses the optimal join order as well as the optimal index for each table. The join order can affect which index is the best choice. The optimizer can choose an index as the access path for a table if it is the inner table, but not if it is the outer table (and there are no further qualifications).

优化器只在简单FROM子句中选择表的连接顺序。使用JOIN关键字的大多数连接都被简化为简单连接,因此优化器会选择它们的连接顺序。

优化器不会为外部连接选择连接顺序;它使用语句中指定的顺序。

当选择连接顺序时,优化器会考虑: 每个桌子的大小 每个表上可用的索引 表上的索引在特定的连接顺序中是否有用 在每个连接顺序中为每个表扫描的行数和页数

对于INNER连接,不,顺序不重要。查询将返回相同的结果,只要您将SELECT *改为SELECT a.*, b.*, c.*。


对于(LEFT, RIGHT或FULL) 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

等价于:

a LEFT JOIN c 
    ON c.ac_id = a.ac_id
  LEFT JOIN b
    ON b.ab_id = a.ab_id

but:

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

不等于:

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

另一个(希望更简单)结合性的例子。可以把它想成(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

这相当于一个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

只是因为我们有“不错”的ON条件。ON b.ab_id = a.ab_id和c.bc_id = b.bc_id都是相等性检查,不涉及NULL比较。

您甚至可以使用其他操作符或更复杂的操作符设置条件,如:ON a.x <= b.x或ON a.x = 7或ON a.x like b.x或ON (a.x, a.y) = (b.x, b.y),这两个查询仍然是等效的。

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

对于常规的join,则不会。TableA连接TableB将产生与TableB连接TableA相同的执行计划(因此您的C和D示例将是相同的)

对于左右连接是这样的。TableA左连接TableB与TableB左连接TableA不同,但与TableB右连接TableA相同

如果你在加入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

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