我一直很难在Google上搜索答案,但.... 有人可以向我解释将JOIN的ON条件与JOIN本身相对而将ON置于所有其他JOIN的末尾之间的区别。
这是一个示例http://sqlfiddle.com/#!3/e0a0f/3
CREATE TABLE TableA (Email VARCHAR(100), SomeNameA VARCHAR(100))
CREATE TABLE Tableb (Email VARCHAR(100), SomeNameB VARCHAR(100))
CREATE TABLE Tablec (Email VARCHAR(100), SomeNameC VARCHAR(100))
INSERT INTO TableA SELECT 'joe@test.com', 'JoeA'
INSERT INTO TableA SELECT 'jan@test.com', 'JaneA'
INSERT INTO TableA SELECT 'dave@test.com', 'DaveA'
INSERT INTO TableB SELECT 'joe@test.com', 'JoeB'
INSERT INTO TableB SELECT 'dave@test.com', 'DaveB'
INSERT INTO TableC SELECT 'joe@test.com', 'JoeC'
INSERT INTO TableC SELECT 'dave@test.com', 'DaveC'
SELECT TOP 2 a.*,
b.*,
c.*
FROM TableA a
LEFT OUTER JOIN TableB b
ON a.email = b.email
INNER JOIN TableC c
ON c.Email = b.email;
SELECT TOP 2 a.*,
b.*,
c.*
FROM TableA a
LEFT OUTER JOIN TableB b
INNER JOIN TableC c
ON c.Email = b.email
ON a.email = b.email;
我不明白为什么这两个SELECT语句会产生不同的结果。
答案 0 :(得分:12)
重要的是连接顺序。将表达式视为每个连接都产生临时“虚拟”表。
所以当你写
FROM TableA a
LEFT OUTER JOIN TableB b ON a.email = b.email
INNER JOIN TableC c ON c.Email = b.email ;
然后订单如下:
TableA
与[{1}}联系,产生临时关系TableB
V1
内部加入了V1
。写作时的意思是:
TableC
然后订单如下:
FROM TableA a
LEFT OUTER JOIN TableB b
INNER JOIN TableC c ON c.Email = b.email ON a.email = b.email;
与TableB
内部联系,产生临时关系TableC
。V1
已加入TableA
。因此结果不同。通常建议在这种情况下使用括号来提高查询的可读性:
V1
答案 1 :(得分:4)
在第二个示例中,ON a.email = b.email
部分属于LEFT JOIN
如果这样写,则表示以下内容:
INNER JOIN
TableC与TableB和LEFT OUTER JOIN
结果与TableA。
结果将是TableA中的所有行与TableB中的那些行连接,这些行在TableC中也有一个条目。
第一个例子意味着以下内容:
LEFT OUTER JOIN
TableB与TableA和INNER JOIN
TableC与结果。这相当于对TableB使用INNER JOIN
说明:当您使用TableB LEFT OUTER JOIN
TableA时,您将获得TableA中的所有行,并且对于TableB中的匹配行,您也将获得该数据。在结果集中,您将拥有b.email
= NULL
的行,现在将使用TableC INNER JOIN
。只要TableC中没有email
= NULL
的条目,您就会得到您观察到的结果。