SELECT (For All Entries、 JOIN)

17.3 SELECT (For All Entries、 JOIN)

3. SELECT (For All Entries、 JOIN)

ここでは、データベースのアクセス方法として以下を説明します。

  • For All Entries
  • JOIN

SELECT(JOIN)

  JOINは「結合」とも呼ばれ、一度のSELECT命令で、複数テーブルからレコードを抽出することが可能です。また結合には内部結合と外部結合の2種類があります。

内部結合

内部結合は、結合しているすべてのテーブルに存在するデータを抽出します。
抽出する際に、結合しているすべてのテーブルにデータが存在しない場合は、
抽出せずにスキップします。

外部結合

外部結合は、基準となるテーブルにデータが存在する場合に抽出します。
内部結合と違い、結合しているすべてのテーブルにデータが存在しない場合も抽出します。
つまり、該当レコードが、スキップされずにすべて取得されます。

SELECT(JOIN)FROM句

結合なしのSELECT命令と同様に、FROM句には抽出先のデータベーステーブルを指定します。
また、結合する場合に限り、選択したテーブルに任意の別名をつけることができ、データベーステーブル名を逐一、書く必要がなくなります。
この別名は、同SELECT命令外では、機能しないので注意しましょう。

抽出元のデータベーステーブルは<DBtab1>で、<別名1>と記します、という意味です。

SELECT(JOIN)INNER JOIN(内部結合)/OUTER JOIN(外部結合)句

ここでは、FROM句で指定したテーブルと、結合させたいデータベーステーブルを指定することができます。
FROM句と同様に、抽出先のデータベーステーブルに、任意の別名をつけることができます。

内部結合するデータベーステーブルは<DBtab2>で、<別名2>と記します、という意味です。

外部結合するデータベーステーブルは<DBtab2>で、<別名2>と記します、という意味です。

SELECT(JOIN)ON句

ここでは、結合条件を指定します。
この結合条件を満たしたレコードからのみ抽出することができます。
これにより、任意の項目を抽出したとしても、結合先のデータベーステーブルから抽出するデータとの整合性を保つことができます。
条件の指定方法は、WHERE句とほぼ同様ですが、それぞれの項目名が、どのデータベースの項目なのかを記述する必要があります。

データベーステーブル<DBtab1>の<項目名1>と、データベーステーブル<DBtab2>の<項目名2>が等しいレコードを結合しなさい、という意味です。

SELECT(JOIN)WHERE句

WHERE句は抽出条件を指定します。
結合なしのSELECT文と異なる点は、複数テーブルから同時に抽出するため、
条件を記述する際に、それぞれの項目名が、どのデータベースの項目なのかを記述する必要があります。

SELECT INNER JOINの構文例

この構文例の意味について、コードの記載順に説明していきます。

ここでは、データベーステーブルから抽出する項目を指定しています。
抽出する項目は、
 Aの項目:CARRID(航空会社コード)
 Aの項目:CONNID(フライト接続番号)
 Aの項目:FLDATE(フライト日付)
 Bの項目:CITYFROM(到着都市)
 Bの項目:CITYTO(出発都市)
となります。
(※AとBについては次で説明しています。)

FROM句には、抽出したいデータベーステーブル名を記述します。
データベーステーブル:SFLIGHT(フライト)から抽出し、別名をAと記します。

INNER JOIN句には、 結合させたいデータベーステーブル名を記述します。
データベーステーブル:SPFLI(フライトスケジュール)を内部結合し、別名をBと記します。

ON句には、結合条件が書かれています。
Aの項目:CARRID(航空会社コード)が、Bの項目:CARRID(航空会社コード)と等しい、かつ、Aの項目:CONNID(フライト接続番号)が、Bの項目:CONNID(フライト接続番号)に等しいデータを結合します。
内部結合ですので、AとB両方のデータベーステーブルにデータが存在するレコードのみ結合されます。

INTO TABLE句には、取得したデータを格納する内部テーブルを指定します。
取得したデータは内部テーブル:TAB_FLIGHTに格納します。

WHERE句では、抽出条件を指定しています。
Aの項目:FLDATE(フライト日付)が、2021年12月31日より前のデータが抽出対象になります。

構文例の内部結合のイメージ

SELECT LEFT OUTER JOINの構文例

先ほどの内部結合の構文例との違いは、青字部分の記載が、
LEFT OUTER JOIN(外部結合)か、INNER JOIN(内部結合)か、のみです。

この構文例の意味については、コードの違う以下の部分についてのみ説明します。

LEFT OUTER JOIN句には、 結合させたいデータベーステーブル名を記述します。
データベーステーブル:SPFLI(フライトスケジュール)を外部結合し、別名をBと記します。

構文例の外部結合のイメージ

SELECT(For All Entries)

For All Entries命令では、指定した内部テーブルに含まれるレコードの項目の組み合わせを抽出対象として、一括検索することができます。
ループで、内部テーブルの値を1件ずつ抽出条件に指定しなくても、FOR ALL ENTRIESを
使えば、一括で抽出することができます。

注意事項

ただし、指定した検索用内部テーブルが0件の場合は、全件選択となってしまうため、
FOR ALL ENTRIES を使用する前には、必ずIF命令などを利用して、検索用内部テーブルの件数を確認しましょう。

データが読み込まれるまでの流れ

この例では、検索用内部テーブルを検索条件として、DBテーブルからデータを読み込み、取得用内部テーブルに格納しています。

すなわち、DBテーブルから、
項目:Aの値が001、かつ、項目:Bの値がAのレコード、
および
項目:Aの値が003、かつ、項目:Bの値がCのレコード、
を読み込み、取得用内部テーブルに格納しています。

サンプルコード SELECT(For All Entries)

REPORT ZCUSLIST1_INTERNAL_ALLENTRIES.
DATA  wa_data TYPE ZTEST_TBL_002.
DATA: t_data    TYPE STANDARD TABLE OF ZTEST_TBL_002,  "取得用
          t_index   TYPE STANDARD TABLE OF ZTEST_TBL_001.  "検索用

START-OF-SELECTION.

*(1) 生徒情報マスタ(ZTEST_TBL_001)から以下のデータを内部テーブルへ読み込みます。
SELECT * FROM ZTEST_TBL_001 INTO TABLE t_index
WHERE grade = 1 AND class = 'A' AND num <= 2.

*(2) (1)で用意した内部テーブルを検索用内部テーブルとして、
*   生徒別テスト得点情報テーブル(ZTEST_TBL_002)の読み込みを行います。
*   以下の生徒別テスト得点情報テーブルデータから、
*   検索用内部テーブルと検索キー項目(grade,class,num)が一致するデータを読み込みます。
SELECT *
FROM   ZTEST_TBL_002
INTO TABLE  t_data
FOR ALL ENTRIES IN t_index
WHERE  grade = t_index-grade
AND    class  = t_index-class
AND    num  = t_index-num.
*ヘッダの帳票出力
WRITE: 001(4) '学年', 010(2) '組',020(8) '出席番号', 030(10) 'テスト名',
            050(4) '国語', 055(4) '英語', 060(4) '数学',
            /001(65) '************************************************'.

LOOP AT t_data INTO wa_data.
*(3) (2)で読み込んだ内部テーブルを帳票出力します。
WRITE: /001(1) wa_data-grade,  010(2) wa_data-class, 020(2) wa_data-num, 030(10) wa_data-testname, 050(3) wa_data-japanese,
055(3) wa_data-english, 060(3) wa_data-math.
  NEW-LINE.
ENDLOOP.

データが読み込まれるまでの流れ

データベーステーブル:ZTEST_TBL_002(生徒別テスト得点情報テーブル)から、項目:GRADE(学年)、CLASS(組)、NUM(出席番号)の値が、検索用内部テーブル:T_INDEXの項目:GRADE(学年)、CLASS(組)、NUM(出席番号)の値と一致(赤枠部分)するデータを取得し、取得用内部テーブル:T_DATAに格納します。(緑枠部分)

出力結果


NEXT>> 第18章 ABAP SQL③