2つ以下のクエリがLeft Outer JoinまたはRight Outer Joinの例であるかどうか、誰にでも教えてもらえますか。
Table Part:
Name Null? Type
PART_ID NOT NULL VARCHAR2(4)
SUPPLIER_ID VARCHAR2(4)
PART_ID SUPPLIER_ID
P1 S1
P2 S2
P3
P4
Table Supplier:
Name Null? Type
SUPPLIER_ID NOT NULL VARCHAR2(4)
SUPPLIER_NAME NOT NULL VARCHAR2(20)
SUPPLIER_ID SUPPLIER_NAME
S1 Supplier#1
S2 Supplier#2
S3 Supplier#3
サプライヤが供給しているかどうかに関係なく、すべての部品を表示します。
パートP、サプライヤSからのP.Part_Id、S。Supplier_Name を選択します。パートP、サプライヤS からの選択P.Part_Id、S.Supplier_Name
TableA LEFT OUTER JOIN TableB
はTableB RIGHT OUTER JOIN Table A
と同等です。
Oracleでは、(+)
はJOINの "optional"テーブルを表します。だからあなたの最初のクエリでは、それはP LEFT OUTER JOIN S
です。 2番目のクエリでは、それはS RIGHT OUTER JOIN P
です。 それらは機能的に同等です。
用語では、RIGHTまたはLEFTは結合のどちら側に常にレコードがあるかを指定し、もう一方の側はNULLになることがあります。そのためP LEFT OUTER JOIN S
では、P
は常にLEFT
上にあるのでレコードを持ちますが、S
はnullになることがあります。
追加の説明については、 Java2s.comのこの例 を参照してください。
はっきりさせるために、私は用語が問題にならないと言っているのではないかと思います。重要なのは、それがどのように機能するのかという概念を理解していることです。
暗黙的な結合構文でRIGHTとLEFTを決定する際に何が重要かについて混乱しています。
左外部結合
SELECT *
FROM A, B
WHERE A.column = B.column(+)
右外部参加
SELECT *
FROM A, B
WHERE B.column(+) = A.column
私がしたのは、WHERE句の用語の入れ替えだけですが、機能的には同等です。 (+)
の位置はRIGHTかLEFTかを決定します。 (具体的には、(+)
が右側にある場合は左結合です。(+)
が左側にある場合は右結合です。)
JOINの2つのスタイルは、暗黙のJOINとの明示的JOINです。それらはJOINを書くのに異なるスタイルですが、それらは機能的に同等です。
this SO question を参照してください。
暗黙のJOINは単にすべてのテーブルをまとめてリストします。結合条件はWHERE句で指定されます。
暗黙的な結合
SELECT *
FROM A, B
WHERE A.column = B.column(+)
明示的なJOINは、結合条件をWHERE句ではなく特定のテーブルの包含に関連付けます。
明示的なJOIN
SELECT *
FROM A
LEFT OUTER JOIN B ON A.column = B.column
これらの暗黙のJOINは、読みやすく理解しづらい場合があります。また、結合条件が他のWHERE条件に混在しているため、いくつかの制限もあります。そのため、暗黙的なJOINは一般的に、明示的な構文を支持して推奨されます。
これら2つのクエリはOUTER JOIN
を実行しています。下記参照
Oracleの結合演算子ではなく、FROM句のOUTER JOIN構文を使用することをお薦めします。 Oracleの結合演算子(+)を使用する外部結合問合せには、FROM句のOUTER JOIN構文には適用されない、次の規則と制限があります。
FROM句の結合構文も含まれているクエリブロックに(+)演算子を指定することはできません。
(+)演算子は、WHERE句、またはFROM句の左相関(TABLE句を指定する場合)のコンテキストでのみ使用でき、テーブルまたはビューの列にのみ適用できます。
AとBが複数の結合条件で結合されている場合は、これらすべての条件で(+)演算子を使用する必要があります。そうでない場合、Oracle Databaseは単純結合の結果である行のみを戻しますが、外部結合の結果がないことを警告またはエラーなしで通知します。
(+)演算子は、外部クエリで1つのテーブルと内部クエリでもう1つのテーブルを指定した場合、外部結合を生成しません。
自己結合は有効ですが、(+)演算子を使用して表をそれ自体に外部結合することはできません。たとえば、次の文は無効です。
-- The following statement is not valid: SELECT employee_id, manager_id FROM employees WHERE employees.manager_id(+) = employees.employee_id;
ただし、次の自己結合は有効です。
SELECT e1.employee_id, e1.manager_id, e2.employee_id FROM employees e1, employees e2 WHERE e1.manager_id(+) = e2.employee_id ORDER BY e1.employee_id, e1.manager_id, e2.employee_id;
(+)演算子は列にのみ適用でき、任意の式には適用できません。ただし、任意の式に(+)演算子でマークされた1つ以上の列を含めることができます。
(+)演算子を含むWHERE条件は、OR論理演算子を使用して別の条件と組み合わせることはできません。
WHERE条件では、IN比較条件を使用して、(+)演算子でマークされた列を式と比較することはできません。
WHERE句に、表Bの列と定数とを比較する条件が含まれている場合は、その列にNULLを生成した表Aの行をOracleが返すように、その列に(+)演算子を適用する必要があります。それ以外の場合、Oracleは単純結合の結果のみを返します。
2組以上の表の外部結合を実行する照会では、単一の表が他の1つの表に対してのみNULL生成表になることがあります。このため、AとBの結合条件およびBとCの結合条件で、Bの列に(+)演算子を適用することはできません。外部結合の構文については、SELECTを参照してください。
から引用した http://download.Oracle.com/docs/cd/B28359_01/server.111/b28286/queries006.htm
上記の回答でいくつかの矛盾がありました。Oracle12cで次のことを試したところ、次のようになりました。
左外部結合
SELECT *
FROM A, B
WHERE A.column = B.column(+)
右外部参加
SELECT *
FROM A, B
WHERE B.column(+) = A.column