SQLを見てるとたまにWHERE句内で「(+)」と記載されているのを見かけることがあります。
この「(+)」はOracle独自で記載が可能となる外部結合演算子といって、「g.GOODS_CODE = gt.GOODS_CODE(+)」のように指定するとLEFT OUTER JOINと同じ結果を取得することが出来ます。
サンプルテーブル
外部結合演算子を利用したクエリー(SQL)例
1 2 3 |
SELECT g.name, gt.type_name FROM USER1.GOODS g, USER1.GOODS_TYPE gt WHERE g.GOODS_CODE = gt.GOODS_CODE(+); |
通常の左外部結合でのクエリー(SQL)例
1 2 3 |
SELECT g.name, gt.type_name FROM USER1.GOODS g LEFT OUTER JOIN USER1.GOODS_TYPE gt ON g.GOODS_CODE = gt.GOODS_CODE; |
実行結果
外部結合演算子、左外部結合どちらも同じ結果となります。
補足
-
「(+)」演算子の歴史的背景
Oracle の古いバージョンからサポートされていた外部結合の書き方で、ANSI SQL 標準が普及する以前によく使われていました。ANSI 標準(LEFT JOIN
/RIGHT JOIN
/FULL OUTER JOIN
)が登場して以降は、可読性・移植性の観点から推奨されないことが多いです。 -
制限・注意点
-
可読性・保守性:
g.GOODS_CODE = gt.GOODS_CODE(+)
のような記述は、JOIN の方向やどのテーブルに外部結合をかけているかが分かりにくく、後でクエリを読む人が迷いやすいです。 -
複雑な結合:複数テーブルを結合する場合、どこに
(+)
を付けるか、また付け方によって結果が変わるため、注意深く設計する必要があります。 -
NULL の扱い:外部結合によって NULL が返る行が含まれますが、条件節で他の条件と組み合わせると意図しない行の除外が起きることがあります(例えば WHERE 節で
AND
条件として別の非 NULL 条件を加えると外部結合の意味が薄れる等)。
-
-
ANSI 標準との違い
項目 (+) 外部結合演算子 ANSI SQL 外部結合 (LEFT OUTER JOIN 等) 可読性 やや分かりにくい 比較的分かりやすい 移植性 Oracle に依存 多くの RDBMS でサポートされる 複雑な JOIN の組み立て エラーや誤解の元になりやすい ON 句で明示的に指定できるため制御しやすい サポート状況 最新 Oracle でも非推奨の方向 推奨される方式 -
現代のベストプラクティス
-
新規開発では ANSI SQL の外部結合構文を使うことを推奨。可読性や他 DBMS への移植性が高いため。
-
既存システムで
(+)
を使っているなら、リファクタリングやドキュメント整備を行い、「なぜこの構文になっているか」「どのような影響があるか」を明らかにしておく。 -
テストを用意して、クエリ変更後に結果が同じになることを検証する(特に NULL の扱いや結合の漏れが起きていないか)。
-
-
実際の書き換え例
旧構文を ANSI 標準に書き換えるときの例をもう一つ:
-
互換性・移行のヒント
-
Oracle のバージョンによっては
(+)
構文が将来削除される可能性があり、非推奨の警告が出ることもあります。 -
他の RDBMS(PostgreSQL、MySQL、SQL Serverなど)で同じSQLを使うことを想定するなら、ANSI JOINに統一しておくと移行がスムーズです。
-
クエリのパフォーマンスにも注意。古い構文でも Oracle のオプティマイザが合理化する場合がありますが、可視性や保守性を取る方が長期的には有利。
-