web-dev-qa-db-ja.com

Oracle 11gで+記号を使用した左外部結合

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 
78
Mike

TableA LEFT OUTER JOIN TableBTableB 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のこの例 を参照してください。


はっきりさせるために、私は用語が問題にならないと言っているのではないかと思います。重要なのは、それがどのように機能するのかという概念を理解していることです。


右vs左

暗黙的な結合構文でRIGHTとLEFTを決定する際に何が重要かについて混乱しています。

左外部結合

SELECT *
FROM A, B
WHERE A.column = B.column(+)

右外部参加

SELECT *
FROM A, B
WHERE B.column(+) = A.column

私がしたのは、WHERE句の用語の入れ替えだけですが、機能的には同等です。 (+)の位置はRIGHTかLEFTかを決定します。 (具体的には、(+)が右側にある場合は左結合です。(+)が左側にある場合は右結合です。)


JOINの種類

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は一般的に、明示的な構文を支持して推奨されます。

179
Wiseguy

これら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

8
Rahul

上記の回答でいくつかの矛盾がありました。Oracle12cで次のことを試したところ、次のようになりました。

左外部結合

SELECT *
FROM A, B
WHERE A.column = B.column(+)

右外部参加

SELECT *
FROM A, B
WHERE B.column(+) = A.column
2
Charles