左外部結合が可換でない理由は簡単に理解できますが、それらが結合的であるかどうかを理解するのに問題があります。いくつかのオンラインソースはそうではないと示唆していますが、私はこれが事実であると自分自身に納得させることができませんでした。
A、B、Cの3つのテーブルがあるとします。
AにIDとB_IDの2つの列が含まれているとします。ここで、IDはテーブルAの主キーであり、B_IDはテーブルBの主キーに対応する外部キーです。
BにIDとC_IDの2つの列が含まれているとします。ここで、IDはテーブルBの主キーであり、C_IDはテーブルCの主キーに対応する外部キーです。
CにIDとVALUEの2つの列が含まれているとします。ここで、IDはテーブルCの主キーであり、VALUEには任意の値が含まれています。
では、_(A left outer join B) left outer join C
_はA left outer join (B left outer join C)
と等しくてはいけませんか?
あなたの質問が示唆しているように、あなたが外部キーに参加していると仮定しているなら、そうです、そうです、 Przemyslaw Kruglejの答え でカバーされているように、OUTERJOINは連想的であることが保証されていると思います。
ただし、実際にJOIN条件を指定していないことを考えると、根本的に正しい答えは、いいえ、それらが関連付けられるとは限らないということです。ひねくれたON
句との結合性に違反する簡単な方法は2つあります。
これは結合性を侵害するためのかなり安価な方法ですが、厳密に言えば、あなたの質問ではそれを禁じるものは何もありません。質問で提案された列名を使用して、次の2つのクエリを検討してください。
-- This is legal
SELECT * FROM (A JOIN B ON A.b_id = B.id)
JOIN C ON (A.id = B.id) AND (B.id = C.id)
-- This is not legal
SELECT * FROM A
JOIN (B JOIN C ON (A.id = B.id) AND (B.id = C.id))
ON A.b_id = B.id
下のクエリは有効なクエリでもありませんが、上のクエリは有効です。明らかに、これは結合性に違反します。
このようにして、JOINの順序に応じて、結果セットに異なる数の行を含めることもできます。たとえば、BでAを結合する条件をA.b_id = B.id
としますが、CでBを結合する条件をB.id IS NULL
とします。
したがって、出力が大きく異なる次の2つのクエリを取得します。
SELECT * FROM (A LEFT OUTER JOIN B ON A.b_id = B.id)
LEFT OUTER JOIN C ON B.id IS NULL;
SELECT * FROM A
LEFT OUTER JOIN (B LEFT OUTER JOIN C ON B.id IS NULL)
ON A.b_id = B.id;
ここで実際の動作を確認できます: http://sqlfiddle.com/#!9/d59139/1
このスレッドでは、それらは結合的ではないと言われています: LEFT OUTER JOINは結合的ですか?
ただし、オンラインで、左端と右端のテーブルに共通の属性がない場合( ここ )、外部結合は結合的であると記載されている本を見つけました。
グラフィカルなプレゼンテーション(MSPaint ftw)は次のとおりです。
それを見る別の方法:
テーブルAがBと結合し、BがCと結合すると言ったので、次のようになります。
あなたが説明した条件で、LEFT結合のシーケンスによってはデータが失われる可能性はないと思います。
Tilakが回答で提供したデータ(現在は削除されています)に基づいて、簡単なテストケースを作成しました。
CREATE TABLE atab (id NUMBER, val VARCHAR2(10));
CREATE TABLE btab (id NUMBER, val VARCHAR2(10));
CREATE TABLE ctab (id NUMBER, val VARCHAR2(10));
INSERT INTO atab VALUES (1, 'A1');
INSERT INTO atab VALUES (2, 'A2');
INSERT INTO atab VALUES (3, 'A3');
INSERT INTO btab VALUES (1, 'B1');
INSERT INTO btab VALUES (2, 'B2');
INSERT INTO btab VALUES (4, 'B4');
INSERT INTO ctab VALUES (1, 'C1');
INSERT INTO ctab VALUES (3, 'C3');
INSERT INTO ctab VALUES (5, 'C5');
SELECT ab.aid, ab.aval, ab.bval, c.val AS cval
FROM (
SELECT a.id AS aid, a.val AS aval, b.id AS bid, b.val AS bval
FROM atab a LEFT OUTER JOIN btab b ON (a.id = b.id)
) ab
LEFT OUTER JOIN ctab c ON (ab.bid = c.id)
ORDER BY ab.aid
;
AID AVAL BVAL CVAL ---------- ---------- ---------- ---------- 1 A1 B1 C1 2 A2 B2 3 A3
SELECT a.id, a.val AS aval, bc.bval, bc.cval
FROM
atab a
LEFT OUTER JOIN (
SELECT b.id AS bid, b.val AS bval, c.id AS cid, c.val AS cval
FROM btab b LEFT OUTER JOIN ctab c ON (b.id = c.id)
) bc
ON (a.id = bc.bid)
ORDER BY a.id
;
ID AVAL BVAL CVAL ---------- ---------- ---------- ---------- 1 A1 B1 C1 2 A2 B2 3 A3
この特定の例では、両方のソリューションで同じ結果が得られるようです。これらのクエリが異なる結果を返すようにする他のデータセットは考えられません。
SQLFiddleで確認してください:
以前の回答に加えて:このトピックは、Michael M. David、Advanced ANSI SQL Data Modeling and Structure Processing、Artech House、1999年、19〜21ページでうまく説明されています。利用可能なページ オンライン 。
テーブル(LEFT JOIN ...)と結合句(ON ...)を別々に検討する必要があるため、結合性は両方(テーブル句の再配置と再配置)を参照できると彼が説明していることは特に注目に値します。結合条件、つまり節)。したがって、結合性の概念は、たとえば数値の加算の場合と同じではなく、2つの次元があります。