这两个查询是否等效(假设表格中有不同的/任何类型的数据)?是否有任何情况会导致不同的结果?
查询1:
select * from tablea a
left join tableb b on a.keyacol = b.keybcol
inner join tablec c on c.keyccol = b.keybcol;
查询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;
答案 0 :(得分: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) ;
结果:
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 |
----------------------
至于为什么会发生这种情况,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 |
----------------------
答案 1 :(得分:3)
INNER JOIN 关键字在至少有一个匹配项时返回行 两个表/选择。如果
tableb
中有行没有 <{1}}中的匹配项,不会列出这些行。LEFT JOIN 关键字返回左表中的所有行 (
tablec
),即使右表中没有匹配项(tablea
或tableb
选择)。
由于左连接返回所有行,如果第一个查询的内连接中没有任何对应匹配,则两个查询可能不同。这些行不会在第一个查询中被选中,但会出现在第二个查询中,因为它使用了左连接。
另一个不同的是柱子。但是,由于sub
您将从所有表格/选择中选择所有列并且:
这不是问题。
所以否,它们是等价的。
答案 2 :(得分:3)
他们不等同。
基本上,这里有四种情况,对于A:
上的记录两个查询都将返回方案1的相同值。
但是,它们将为其他方案返回不同的值 - 第一个查询中B值与C值的内部连接意味着您将尝试在其他方案中将null连接到值C