LoginSignup
2
0

More than 1 year has passed since last update.

【ABAP】SQL - INNER JOIN / OUTER JOIN

Posted at
ABAPでSELECT処理でよく使われるINNER JOINとOUTER JOINについて、具体的に何が違うのか見ていきます。新しいABAPで追加された手法も紹介します。

INNER JOINとOUTER JOINの違い

言葉で書くとそのままですね。

  • INNER JOIN(内部結合)
  • OUTER JOIN(外部結合)

それでは取得されるデータはどう変わるのでしょうか。

サンプルデータ

キー項目(CARRID)を結合条件として、2つのテーブルの結合をした場合の違いを確認します。

  • 左テーブル(SCARR)
  • 右テーブル(SPFLI)

①INNER JOIN

左右のテーブルの結合条件が合致するデータのみ取得するのがINNER JOINです。

絵で表すと、円が重なった部分のみが取得対象になります。

サンプルコード

SELECT
scarr~carrid,
scarr~carrname,
spfli~connid
FROM scarr
INNER JOIN spfli
ON spfli~carrid = scarr~carrid
INTO TABLE @it_main.

②LEFT OUTER JOIN

左テーブルの全レコードと結合条件に合致する右テーブルを取得するのがLEFT OUTER JOINです。結合条件に合致しない右テーブルの項目の値は取得されません。

サンプルコード

SELECT
scarr~carrid,
scarr~carrname,
spfli~connid
FROM scarr
LEFT OUTER JOIN spfli
ON spfli~carrid = scarr~carrid
INTO TABLE @it_main.

③RIGHT OUTER JOIN

右テーブルの全レコードと結合条件に合致する左テーブルを取得するのがRIGHT OUTER JOINです。結合条件に合致しない左テーブルの項目の値は取得されません。

項目IDとAirlineは左テーブルの値を取得しているので、結合条件に合致しない左テーブルのデータは取得されていません。

サンプルコード

SELECT
scarr~carrid,
scarr~carrname,
spfli~connid
FROM scarr
RIGHT OUTER JOIN spfli
ON spfli~carrid = scarr~carrid
INTO TABLE @it_main.

LEFT OUTER JOINとRIGHT OUTER JOIN

結論から先に書くと、RIGHT OUTER JOINを使うことはまずないです。

なぜなら、LEFT OUTER JOINと動きが同じだからです。テーブルの左右を入れ替えれば全く同じ結果が得られます。

実際のプロジェクトでもRIGHT OUTER JOINが使われているところは見たことがありません。

テーブル結合は最低限INNER JOINとLEFT OUTER JOINの2つを覚えておけば十分です。

ABAP 7.40以降で使える表現

外部結合時の条件(WHERE句)指定

まずは新旧ABAPでの書き方を比較してみましょう。

※実行環境はABAP7.52

ABAP740未満(不可)

SELECT
scarr~carrid
scarr~carrname
spfli~connid
INTO TABLE it_main
FROM spfli
LEFT OUTER JOIN scarr
ON scarr~carrid = spfli~carrid
WHERE scarr~carrid IN s_carrid.

ABAP740以降(可能)

SELECT
scarr~carrid,
scarr~carrname,
spfli~connid
FROM spfli
LEFT OUTER JOIN scarr
ON scarr~carrid = spfli~carrid
WHERE scarr~carrid IN @s_carrid
INTO TABLE @it_main.

実際に両者を書いてみると、左側の従来の書き方では有効化時にエラーが発生します。

(ABAP7.40以降の環境でも、従来の書き方をすれば有効化エラーになります)

理由は、従来のABAPではWHERE句に外部結合先のテーブル項目を指定できないから、です。

従来のABAPでWHERE句に指定できるのは、

  • 内部結合なら左右どちらのテーブル項目も指定可
  • 外部結合なら元テーブル(LEFT OUTER JOINなら左テーブル)の項目のみ指定可

という制限がありました。

そのため従来のABAPではやり方を工夫して、WHERE句に指定するのが単一項目(= で指定できる)なら結合条件(JOIN句)の中で指定する、レンジテーブルではその手法も使えないので、まず大元のテーブルを取得し、FOR ALL ENTRIES INでもう一方のテーブルを取得するなどの対応をしてました。

それがABAP7.40以降は、新しい表現で書くことによって、WHERE句に外部結合先のテーブル項目を指定できるようになりました。

新しいABAPでは以下のルールがあるので、最初は慣れないと思いますが注意してください。

  • 複数項目を抽出する際、最終項目以外はカンマで区切る
  • 外部変数(内部テーブルや変数、選択画面項目にはエスケープ文字(@)を付与

もう一つ、INTO TABLEの位置が新旧で異なりますが、これもABAP7.40以降の新しい表現で、INTO TABLEを文末に持ってくることができるようになりました。ただし、従来通りの位置に書くこともできるので、好みの問題だと思います。

個人的には、内部テーブルを上の方に書くと、デバッグの際に探しにいくのが面倒なので、文末に書けるのは地味に嬉しいポイントだと思っています。

外部結合テーブルに対する外部結合

見出しだけだとわかりづらいですね。今までは2つのテーブルを結合する場合のコードを見てきましたが、ここで紹介するのは3つ以上のテーブルを結合する場合の話です。

図で表すとこんな感じで、左テーブルと中テーブルを外部結合、中テーブルと右テーブルも外部結合をします。

それでは、以下の3つのテーブルで見ていきます。

  • 左テーブル(SCARR)
  • 中テーブル(SPFLI)
  • 右テーブル(SFLIGHT)

ABAP740未満(不可)

SELECT
scarr~carrid
scarr~carrname
spfli~connid
sflight~fldate
INTO TABLE it_main
FROM scarr
LEFT OUTER JOIN spfli
ON spfli~carrid = scarr~carrid
LEFT OUTER JOIN sflight
ON sflight~carrid = spfli~carrid
AND sflight~connid = spfli~connid.

ABAP740以降(可能)

SELECT
scarr~carrid,
scarr~carrname,
spfli~connid,
sflight~fldate
FROM scarr
LEFT OUTER JOIN spfli
ON spfli~carrid = scarr~carrid
LEFT OUTER JOIN sflight
ON sflight~carrid = spfli~carrid
AND sflight~connid = spfli~connid
INTO TABLE @it_main.

上記サンプルコードのように、従来のABAPでは外部結合テーブルに対する外部結合は認められていませんので、元テーブルのない外部結合をしたい場合は新しいABAPで書くようにしてください。

※右テーブル(SFLIGHT)の結合元が左テーブル(SCARR)であれば従来のABAPでも可能です

まとめ

  • INNER JOINは結合するテーブルの両方に存在するデータが取得される
  • OUTER JOINは元テーブル全件と結合条件に合致するデータが取得される
  • 新しいABAP(7.40)では外部結合で便利な文法が追加された

INNER JOIN、OUTER JOINはABAP開発でよく使われる文法の一つですので参考にしてください。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0