在SQL中,Join和多个JOINS结束后的ON条件有什么不同

Mak*_*yNZ 10 sql sql-server

我一直很难在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;
Run Code Online (Sandbox Code Playgroud)

我不明白为什么这两个SELECT语句会产生不同的结果.

Kub*_*tek 12

重要的是连接顺序.将表达式视为每个连接都生成临时"虚拟"表.

所以当你写作

FROM TableA a 
LEFT OUTER JOIN TableB b ON a.email = b.email
INNER JOIN TableC c ON c.Email = b.email ;
Run Code Online (Sandbox Code Playgroud)

那么订单如下:

  1. TableA留下来加入TableB临时关系V1
  2. V1内心加入TableC.

你写的时候意味着:

FROM TableA a 
LEFT OUTER JOIN TableB b 
INNER JOIN TableC c ON c.Email = b.email ON a.email = b.email;
Run Code Online (Sandbox Code Playgroud)

那么订单如下:

  1. TableB内在联系起来TableC产生临时关系V1.
  2. TableA离开加入V1.

因此结果是不同的.通常建议在这种情况下使用括号来提高查询的可读性:

FROM TableA a 
LEFT OUTER JOIN
  (TableB b INNER JOIN TableC c ON c.Email = b.email)
ON a.email = b.email;
Run Code Online (Sandbox Code Playgroud)