【ABAP】SQL – INNER JOIN / OUTER JOIN

ABAP

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

INNER JOINとOUTER JOINの違い

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

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

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

サンプルデータ

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

①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つのテーブルで見ていきます。

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開発でよく使われる文法の一つですので参考にしてください。

コメント

タイトルとURLをコピーしました