Oracleの「(+)」演算子


155

それらを文書化し、おそらくそれらを拡張する目的で、いくつかの古いSQLステートメントをチェックしています。

DBMSはOracleです

次のような文は理解できませんでした。

select ...
from a,b
where a.id=b.id(+)

(+)演算子について混乱しており、どのフォーラムでも取得できませんでした(引用符内で+を検索しても機能しませんでした)。

とにかく、SQLDeveloperの 'Explain Plan'を使用して、と出力しましたHASH JOIN, RIGHT OUTER

(+)クエリの最後で演算子を削除すると違いはありますか?データベースを(+)使用する前に、いくつかの条件を満たす必要がありますか(インデックスがあるなど)?? あなたが私に簡単な理解、または私がこれについて読むことができるいくつかの良いリンクを提供できれば、それは非常に役に立ちます。

ありがとう!


1
オペレーターではありません。JOINの動作に影響を与えるのは、単なる構文の一部です。
philipxy

回答:


187

ANSI-89形式(FROM句でコンマを使用してテーブル参照を区切る)はOUTER結合を標準化していなかったため、これはOUTER JOINのOracle固有の表記法です。

クエリはANSI-92構文で次のように書き換えられます。

   SELECT ...
     FROM a
LEFT JOIN b ON b.id = a.id

このリンクは、JOINの違いを説明するのに非常に適しています。


正常に(+)動作しても、使用しないことお勧めします

Oracle は、Oracle結合演算子ではなく、FROMOUTER JOIN構文を使用することをお勧めします。Oracle結合演算子を使用する外部結合クエリ(+)には、次の規則と制限が適用されますが、これらはFROM句のOUTER JOIN構文には適用されません。


79
その通りです。(+)を頭の中でまっすぐに保つため(左側と右側)、(+)は「一致が見つからない場合はNULL値を追加する」と考えるのが好きです。たとえば、「a.id = b.id(+)」は、a.idと一致しない場合にb.idをNULLにすることを許可することを意味します。
ビーチ

ありがとう..from句に追加しても同じ結果が得られると思います!!
キランS

:あなたは、公式のOracleドキュメントをリンクしたいことがありdocs.oracle.com/html/A95915_01/sqopr.htm
Vargan

27

(+)演算子は外部結合を示します。つまり、一致がない場合でも、結合の反対側からレコードが返されます。たとえば、aとbがempとdeptで、部門に割り当てられていない従業員がいる場合、次のステートメントは、部門に割り当てられているかどうかに関係なく、すべての従業員の詳細を返します。

select * from emp, dept where emp.dept_id=dept.dept_id(+)

つまり、(+)を削除すると有意差が生じる可能性がありますが、データによってはしばらくの間気付かない場合があります。


25

Oracleでは、(+)はJOINの「オプション」テーブルを示します。したがって、クエリでは、

SELECT a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id=b.id(+)

これは、テーブル 'b'からテーブル 'a'の左外部結合です。反対側(オプションのテーブル 'b')にデータがない場合、データを失うことなくテーブル 'a'のすべてのデータを返します。

左外部結合の図

同じクエリの最新の標準構文は次のようになります

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
LEFT JOIN b ON a.id=b.id

または省略形a.id=b.id(すべてのデータベースでサポートされているわけではありません):

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
LEFT JOIN b USING(id)

(+)を削除すると、通常の内部結合クエリになります

Oracleと他のデータベースの両方での古い構文:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id=b.id

より現代的な構文:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
INNER JOIN b ON a.id=b.id

または単に:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
JOIN b ON a.id=b.id

内部結合の図

「a」と「b」の両方のテーブルの「id」値が同じであるすべてのデータのみが返されます。これは共通部分を意味します。

クエリを正しい結合にしたい場合

これはLEFT JOINとまったく同じですが、オプションのテーブルを切り替えます。

右外部結合の図

古いOracle構文:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id(+)=b.id

最新の標準構文:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
RIGHT JOIN b ON a.id=b.id

参照とヘルプ:

https://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:6585774577187

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

https://www.w3schools.com/sql/sql_join_left.asp


円のラベル「table1」と「table2」は意味がありません。円要素の最も単純な意味は、出力行です。次に、左三日月にはtable1のヌル拡張行が含まれ、右三日月にはtable2のヌル拡張行が含まれます。円の他の意味はあいまいです。図は正確にはどういう意味だと思いますか?他の人の(悪い)プレゼンテーションを盲目的にコピーする以外の方法でそれらを配置したのはなぜですか?
philipxy

これで、円にaとbのラベルが付けられました。円はaとbの行ではありません。左と右の円は、左結合bと右結合bの行に適切にラベルを付けることができます。さらに、これらの円で囲まれた行が入力として何であるかを記述しません。円の中にあるものを自分で考え出す。ラベルaとbをサークルに貼り付ける場合は、各ラベルがサークルとどう関係するかを言葉で明確に説明します。(aとbにラベルを付ける簡単な理由はありません。)グリーンゾーンに正しくラベルを付けたのは良いことです。
philipxy

6

実際には、+記号は条件ステートメント内に直接配置され、オプションのテーブル(条件内に空またはnull値を含めることができるテーブル)の横に配置されます。


(+)は列名のすぐ右側に置かれます。この答えはそれについて明確ではありません。「実際に」とはどういう意味ですか?(修辞的。)(そして、おそらく「ステートメント」を意味するわけではありません。)
philipxy
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.