查询加入等价?

too*_*oop 5 sql database oracle

这两个查询是否等效(假设表中有不同的/任何类型的数据)?是否有任何情况会导致不同的结果?

查询1:

select * from tablea a
left join tableb b on a.keyacol = b.keybcol
inner join tablec c on c.keyccol = b.keybcol;
Run Code Online (Sandbox Code Playgroud)

查询2:

select * from tablea a
left join (
select b.*, c.* from tableb b
inner join tablec c on c.keyccol = b.keybcol
) sub on a.keyacol = sub.keybcol;
Run Code Online (Sandbox Code Playgroud)

ype*_*eᵀᴹ 7

不,他们不等同.例:

CREATE TABLE a
( keya int ) ;

CREATE TABLE b
( keyb int ) ;

CREATE TABLE c
( keyc int ) ;

INSERT INTO a
  VALUES
  (1) ;

INSERT INTO b
  VALUES
  (1),(2) ;

INSERT INTO c
  VALUES
  (2) ;
Run Code Online (Sandbox Code Playgroud)

结果:

SELECT * 
FROM  a
  LEFT JOIN b 
    ON a.keya = b.keyb
  INNER JOIN c 
    ON c.keyc = b.keyb ;

Result
----------------------
| keya | keyb | keyc |
----------------------


SELECT * 
FROM a
  LEFT JOIN 
    ( SELECT b.*, c.* 
      FROM  b
        INNER JOIN c 
          ON c.keyc = b.keyb
    ) sub 
    ON a.keya = sub.keyb ;

Result
----------------------
| keya | keyb | keyc |
----------------------
|   1  | NULL | NULL |
----------------------
Run Code Online (Sandbox Code Playgroud)

至于为什么会发生这种情况,a LEFT JOIN b INNER JOIN c解析为(a LEFT JOIN b) INNER JOIN c等同于(a INNER JOIN b) INNER JOIN c因为连接上的条件INNER取消了LEFT连接.

您也可以在此表单中编写第二个查询 - 没有子查询 - a LEFT JOIN (b INNER JOIN c)由于ON子句的放置不同而被解析:

SELECT * 
FROM a
  LEFT JOIN 
        b
      INNER JOIN c 
        ON c.keyc = b.keyb
    ON a.keya = b.keyb ;

Result
----------------------
| keya | keyb | keyc |
----------------------
|   1  | NULL | NULL |
----------------------
Run Code Online (Sandbox Code Playgroud)