次のようなクエリがあります。
SELECT *
FROM TBLA A
LEFT JOIN TBLB B ON A.Col1 = B.Col2
RIGHT JOIN TBLC C ON B.Col3 = C.Col4
JOIN TBLD D ON C.Col5 = D.Col6
結合はどの順序で解決されますか?私はSQL Serverに最も興味があり、その説明を回答としてマークしますが、ANSI/ISO標準とさまざまなRDBMSでの動作についても同様に興味があります。
この質問の理由は、結果がこのクエリと異なる理由を理解することでした
SELECT *
FROM TBLA A
CROSS JOIN TBLC C
LEFT JOIN TBLB B ON A.Col1 = B.Col2 AND B.Col3 = C.Col4
JOIN TBLD D ON C.Col5 = D.Col6
論理的に結合は、左から右へのON
句の順序で解決されます。
各結合の出力は、次の結合に入る仮想テーブルです。
したがって、質問のクエリでは、A LJ B
の仮想テーブルの結果がC
に結合されます。 B.Col3 = C.Col4
の結合条件は、元の左結合によって保持されていたヌル拡張行をすべて失い、最初の結合を内部結合に効果的に戻し、結果の仮想テーブル(C
からのすべての行を保持する)は次に、D
に結合された内部。
したがって、最初のクエリは次のように簡略化できます。
SELECT *
FROM TBLA A
INNER JOIN TBLB B ON A.Col1 = B.Col2
RIGHT JOIN TBLC C ON B.Col3 = C.Col4
JOIN TBLD D ON C.Col5 = D.Col6
これは(A IJ B) ROJ (C IJ D)
と実質的に同じです
ON
句の順序は、テーブルがクエリに表示される順序と必ずしも同じではありません。これは(C IJ D) LOJ (A IJ B)
に書き換えることもできます
SELECT *
FROM TBLC C
INNER JOIN TBLD D
ON C.Col5 = D.Col6
LEFT JOIN TBLA A
INNER JOIN TBLB B
ON A.Col1 = B.Col2
ON B.Col3 = C.Col4
On句の位置は、単一のテーブルだけではなく、(C IJ D)
と(A IJ B)
から得られる2つの仮想テーブル間で外部結合が実行されることを意味します。
2番目のクエリでは、概念的に、仮想テーブルA x C
がBに結合されたままになり、デカルト積全体が保持されます。次に、その結果が述語C.Col5 = D.Col6
を使用してD
に結合されます。これは、C
とD
の間の内部結合を行わない最終結果から行を排除します。
SELECT *
FROM TBLC C
JOIN TBLD D
ON C.Col5 = D.Col6
CROSS JOIN TBLA A
LEFT JOIN TBLB B
ON A.Col1 = B.Col2
AND B.Col3 = C.Col4
PostgreSQLの場合:
必要に応じて括弧を使用して、ネストの順序を決定します。括弧がない場合、JOINは左から右にネストします。いずれにせよ、JOINはFROMアイテムを区切るコンマよりも強くバインドします。
http://www.postgresql.org/docs/9.1/static/sql-select.html#SQL-FROM