web-dev-qa-db-ja.com

SQL ANSI JOINの優先順位

次のようなクエリがあります。

    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
7
孔夫子

論理的に結合は、左から右への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に結合されます。これは、CDの間の内部結合を行わない最終結果から行を排除します。

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 
8
Martin Smith

PostgreSQLの場合:

必要に応じて括弧を使用して、ネストの順序を決定します。括弧がない場合、JOINは左から右にネストします。いずれにせよ、JOINはFROMアイテムを区切るコンマよりも強くバインドします。

http://www.postgresql.org/docs/9.1/static/sql-select.html#SQL-FROM

3
dezso