10

私はこれに対する答えをグーグルで検索するのに苦労していますが、....誰かがJOINのON条件をJOIN自体と一緒に置くことと他のすべてのJOINの最後にONを置くことの違いを説明できますか? 。

これが例です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;

これらの2つのSELECTステートメントが異なる結果を生成する理由がわかりません。

4

2 に答える 2

12

重要なのは結合の順序です。すべての結合が一時的な「仮想」テーブルを生成したかのように式を扱います。

だからあなたが書くとき

FROM TableA a 
LEFT OUTER JOIN TableB b ON a.email = b.email
INNER JOIN TableC c ON c.Email = b.email ;

その場合、順序は次のとおりです。

  1. TableATableB一時的な関係を生み出すために結合されたままになります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;

その場合、順序は次のとおりです。

  1. TableBTableC一時的な関係を生成するために内部結合されてい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;
于 2012-08-30T11:09:28.317 に答える
4

2番目の例では、パーツON a.email = b.emailはに属していLEFT JOINます。
このように書かれている場合、それは次のことを意味します。

INNER JOINTableCとTableB、およびLEFT OUTER JOIN結果とTableA。

結果は、TableAのすべての行が、TableCにもエントリを持つTableBの行と結合されます。

最初の例は次のことを意味します。

LEFT OUTER JOINTableBとTableAおよびTableCとINNER JOIN結果。これはINNER JOIN、forTableBを使用するのと同じです。
説明:LEFT OUTER JOINTableAとTableBを使用すると、TableAからすべての行が取得され、TableBの行が一致する場合は、そのデータも取得されます。結果セットにはb.email=の行がNULLあり、これはINNER JOINTableCで編集されます。emailTableCに=のエントリがない限り、NULL観察した結果が得られます。

于 2012-08-30T11:03:46.673 に答える