WHERE 句は、満たすべき条件を指定することにより選択される行数を制限します。
WHERE 句は、SELECT 命令と同様に OPEN CURSOR、UPDATE、および DELETE 命令でも使用されます。WHERE 句の標準形式は以下のとおりです。
SELECT... WHERE cond...
WHERE 句の cond 条件は、比較または一連の他の特殊式です。一連の条件を、WHERE 句の単一の条件に結合することができます。条件が動的にプログラミングされる場合もあります。
WHERE 句の条件 cond は論理式に似ていますが、構文とセマンティクスが Standard SQL に従うため、論理式と同一ではありません。WHERE 句の条件では、SELECT 句のように項目名を使用して列の名称を指定します。以下の説明では、s は常に、FROM 句で指定された 1 つのデータベーステーブルの列を表します。条件の結果は、真、偽、不明のいずれかとなります。行は、その条件が真の場合にのみ選択されます。関連する列の 1 つにヌル値が含まれている場合、条件は不明です。
全タイプの比較
任意のデータ型の列の値を他の値と比較するには、以下を使用します。
SELECT... WHERE s operator f...
f は、FROM 句からのデータベーステーブルの他の列、データオブジェクト、またはスカラサブクエリです。
列の集計には、以下の命令を使用することができます。
命令 | 内容説明 |
---|---|
MAX | 列の最大値 |
MIN | 列の最小値 |
AVG | 列の平均 |
SUM | 列の合計 |
COUTN | 値または行のカウント |
関係演算子には、以下の式を使用することができます。
演算子 |
意味 |
EQ |
等しい |
= |
等しい |
NE |
等しくない |
<> |
等しくない |
>< |
等しくない |
LT |
より小さい |
< |
より小さい |
LE |
以下 |
<= |
以下 |
GT |
より大きい |
> |
より大きい |
GE |
以上 |
>= |
以上 |
必要に応じて、オペランドの値は変換されます。変換は、プラットフォームまたはコードページに依存する場合があります。
間隔の値
列の値が特定の間隔内にあるかどうかを確認するには、以下を使用します。
SELECT... WHERE s [NOT]BETWEEN f1 AND f2...
列の値 s がデータオブジェクト f1 と f2 の間にある [ない] 場合、条件は真です。FROM 句の ON 条件で、BETWEEN を使用することはできません。
文字列の比較
列の値がパターンに適合するかどうかを確認するには、以下を使用します。
SELECT... WHERE s [NOT]LIKE f [ESCAPE h]...
列 s の値がデータオブジェクト f のパターンに適合する [適合しない] 場合、条件は真です。このテストは、テキスト項目に対してのみ使用することができます。列のデータ型は英数字でなければなりません。f はデータ型 c でなければなりません。
以下のワイルドカードを f で使用することができます。
● % は任意文字の順序 (スペースを含む) を表します。
● _ は 1 文字を表します。
たとえば、ABC_EFG% は文字列ABCxEFGxyz および ABCxEFG に適合しますが、ABCEFGxyz には適合しません。2 つのワイルドカード文字を比較で明示的に使用する場合は、ESCAPE オプションを使用します。ESCAPE h は、エスケープシンボル h を指定します。h が先頭にあると、ワイルドカードとエスケープシンボル自体はパターン f 内での通常の機能を失います。_ および % の使用方法は、Standard SQL での使用方法と同じです。ABAP の他の箇所での論理式は、別のワイルドカード文字 (+ と *) を使用します。
FROM 句の ON 条件で、LIKE を使用することはできません。
値一覧のチェック
列の値が値一覧に含まれているかどうかを確認するには、以下を使用します。
SELECT... WHERE s [NOT]IN (f1,......, fn)...
列の値 s が一覧 f1 … fn にある [ない] 場合、条件は真です。
サブクエリのチェック
列の値がスカラサブクエリに含まれているかどうかを確認するには、以下を使用します。
SELECT... WHERE s [NOT]IN subquery...
<s> の値がスカラサブクエリ subquery の結果セットに含まれている[いない] 場合、条件は真です。
サブクエリの選択に行が 1 行でも含まれているかどうかを確認するには、以下を使用します。
SELECT... WHERE [NOT] EXISTS subquery...
サブクエリ subquery の結果セットに 1 行でも含まれている [1 行も含まれていない] 場合、この条件は真です。サブクエリがスカラである必要はありません。
FROM 句の ON 条件でサブクエリをチェックすることはできません。
選択テーブルのチェック
列の値が選択テーブルの条件を満たすかどうかを確認するには、以下を使用します。
SELECT... WHERE s [NOT]IN seltab...
s の値が seltab に保存された条件を満たす [満たさない] 場合、この条件は真です。seltab は、実際の選択テーブルまたは RANGES テーブルのいずれかです。FROM 句の ON 条件で選択テーブルをチェックすることはできません。
null 値のチェック
列の値がヌルであるかどうかを確認するには、以下を使用します。
SELECT... WHERE s IS [NOT]NULL...
s の値がヌルである [ない] 場合、条件は真です。
条件の否定
条件の結果を否定するには、以下を使用します。
SELECT... WHERE NOT cond...
cond が偽の場合は条件が真で、cond が真の場合は条件が偽です。不明な条件の結果は、否定された場合も不明のままです。
条件のリンク
AND と OR の演算子を使用して、2 つの条件を 1 つに結合することができます。
SELECT... WHERE cond1 AND cond2...
<cond1> と <cond2> が真の場合、この条件は真です。
SELECT... WHERE cond1 OR cond2...
<cond1> と <cond2> の一方または両方が真の場合、この条件は真です。
NOT は AND よりも優先され、AND は OR よりも優先されます。ただし、括弧を使用して処理順序を制御することもできます。
動的条件
条件を動的に指定するには、以下を使用します。
SELECT... WHERE (itab)...
この itab は、行データ型 c および最大文字長 72 文字の内部テーブルです。選択テーブル以外の上記の条件はすべて、itab の行に書き込むことができます。ただし、リテラルのみを使用して、データオブジェクトの名称は使用しないでください。内部テーブル itab を空白のままにすることもできます。
条件の一部のみを動的に指定する場合は、以下を使用します。
SELECT... WHERE cond AND (itab)...
OR を使用して、静的条件と動的条件をリンクすることはできません。
SELECT 命令の WHERE 句のみで、動的条件を使用することができます。
テーブル条件
SELECT 命令の WHERE 句には、内部テーブルの行と列から条件を導き出す特殊なバリアントがあります。このバリアントは以下のとおりです。
SELECT... FOR ALL ENTRIES IN itab WHERE cond...
cond は、上記のように指定することができます。内部テーブル itab の項目を条件のオペランドとして指定する場合は、内部テーブルのすべての行を指定します。その後、内部テーブルの各行について比較が行われます。各行に対して、データベーステーブルから条件を満たす行が選択されます。SELECT 命令の結果セットは、内部テーブルの各行に対する個々の選択を結合したものです。重複行は自動的に結果セットから除外されます。itabが空の場合は、オプション FOR ALL ENTRIES が無視されて、すべてのエントリが読み込まれます。
内部テーブル itab には構造化された行データ型が必要であり、条件 cond に使用される各項目は、比較対象のデータベースの列と互換性がなければなりません。内部テーブル項目を使用する比較では、演算子 LIKE、BETWEEN および IN を使用しないでください。同じ SELECT 命令では、ORDER BY 句を使用することはできません。
オプション FOR ALL ENTRIES を使用して、ネストされた select ループを内部テーブルでの操作によって置き換えることができます。これにより、選択したデータの大型セットに対するパフォーマンスが大幅に向上します。
WHERE 句の条件:
... WHERE carrid = 'UA'.
列 CARRID にコンテンツ UA がある場合、この条件は真です。
... WHERE num GE 15.
列 NUM に 15 以上の数が含まれている場合、この条件は真です。
... WHERE cityfrom NE 'FRANKFURT'.
列 CITYFROM に文字列 FRANKFURT が含まれない場合、この条件は真です。
... WHERE num BETWEEN 15 AND 45.
列 NUM に 15 から 45 までの数字が含まれる場合、この条件は真です。
... WHERE num NOT BETWEEN 1 AND 99.
列 NUM に 1 から 99 までの数以外の数が含まれる場合、この条件は真です。
... WHERE name NOT BETWEEN 'A' AND 'H'.
列 NAME が 1 文字の長さでそのコンテンツが A から H でない場合、この条件は真です。
... WHERE city LIKE '%town%'.
列 CITY にパターン ‘town’ を含む文字列がある場合、この条件は真です。
... WHERE name NOT LIKE '_n%'.
列 NAME に、2 番目の文字が ‘n’ でない値が含まれている場合、この条件は真です。
... WHERE funcname LIKE 'EDIT#_%' ESCAPE '#'.
列 FUNCNAME のコンテンツが EDIT_ で始まる場合、この条件は真です。
... WHERE city IN ('BERLIN', 'NEW YORK', 'LONDON').
列 CITY に値 BERLIN、NEW YORK、LONDON の 1 つがある場合、この条件は真です。
... WHERE city NOT IN ('FRANKFURT', 'ROM').
列 CITY に値 FRANKFURT または ROME が含まれない場合、この条件は真です。
... .......WHERE ( NUMBER = '0001' OR NUMBER = '0002') AND
列 NUMBER に値 0001 または 0002 が含まれて、列 COUNTRY に F も USA も含まれない場合、この条件は真です。
一般サンプル
SELECT * INTO TABLE itab FROM spfli WHERE col1 = wa1 AND col2 <> wa2 AND col3 IN seltab. // 選択テーブルの場合
動的条件
REPORT demo_select_dynamic_conditions. DATA: cond(72) TYPE c, itab LIKE TABLE OF cond. PARAMETERS: city1(10) TYPE c, city2(10) TYPE c. DATA wa TYPE spfli-cityfrom. CONCATENATE 'CITYFROM = ''' city1 '''' INTO cond. APPEND cond TO itab. CONCATENATE 'OR CITYFROM = ''' city2 '''' INTO cond. APPEND cond TO itab. CONCATENATE 'OR CITYFROM = ''' 'BERLIN' '''' INTO cond. APPEND cond TO itab. LOOP AT itab INTO cond. WRITE cond. ENDLOOP. SKIP. SELECT cityfrom INTO wa FROM spfli WHERE (itab). WRITE / wa. ENDSELECT.
選択画面でパラメータ city1 および city2 に対してFRANKFURT および BERLIN を入力した場合、一覧は以下のように表示されます。
最初の 3 行は、内部テーブル itab の内容を示しています。完全に一致するテーブル行が選択されます。
テーブル条件
REPORT demo_select_for_all_entries_1. DATA: BEGIN OF line, carrid TYPE spfli-carrid, connid TYPE spfli-connid, cityfrom TYPE spfli-cityfrom, cityto TYPE spfli-cityto, END OF line, itab LIKE TABLE OF line. line-cityfrom = 'FRANKFURT'. line-cityto = 'BERLIN'. APPEND line TO itab. line-cityfrom = 'NEW YORK'. line-cityto = 'SAN FRANCISCO'. APPEND line TO itab. SELECT carrid connid cityfrom cityto INTO CORRESPONDING FIELDS OF line FROM spfli FOR ALL ENTRIES IN itab WHERE cityfrom = itab-cityfrom AND cityto = itab-cityto. WRITE: / line-carrid, line-connid, line-cityfrom, line-cityto. ENDSELECT.
出力は以下のようになります。
この例では、以下の条件を満たすすべての行を選択します。
■ CITYFROM 列に FRANKFURT が含まれて、CITYTO 列に BERLIN が含まれている
■ CITYFROM 列に NEW YORK が含まれて、CITYTO 列に SAN FRANCISCO が含まれている
テーブル条件
REPORT demo_select_for_all_entries_2. DATA: tab_spfli TYPE TABLE OF spfli, tab_sflight TYPE SORTED TABLE OF sflight WITH UNIQUE KEY table_line, wa LIKE LINE OF tab_sflight. SELECT carrid connid INTO CORRESPONDING FIELDS OF TABLE tab_spfli FROM spfli WHERE cityfrom = 'NEW YORK'. SELECT carrid connid fldate INTO CORRESPONDING FIELDS OF TABLE tab_sflight FROM sflight FOR ALL ENTRIES IN tab_spfli WHERE carrid = tab_spfli-carrid AND connid = tab_spfli-connid. LOOP AT tab_sflight INTO wa. AT NEW connid. WRITE: / wa-carrid, wa-connid. ENDAT. WRITE: / wa-fldate. ENDLOOP.
出力は以下のようになります。
この例では、テーブル SPFLI の列 CITYFROM に値 NEW YORK が含まれるすべての接続に対して、SFLIGHT からフライトデータを選択します。FROM 句の結合を使用して、単一の SELECT 命令で同じデータを選択することもできます。
内部テーブルを指定する(INTO TABLE)
SELECT * INTO TABLE itab FROM spfli.
既存内部テーブルに新規行を追加する(APPENDING)
SELECT * INTO APPENDING [CORRESPONDING FIELD] TABLE itab FROM spfli.
CORRESPONDING FIELDの使用はオススメしません。
項目などを自動で判別して格納してくれる一見便利そうな機能ですが、その分処理には時間がかかります。
項目の並び順が処理毎に変わらないない限り、取得項目と格納先項目の順番などを合わせて使用しない事をオススメします。
レコードを1件のみ取得する(SINGLE)
SELECT SINGLE * INTO TABLE itab FROM spfli.
他にも、「UP TO 1 ROWS」でも1件のみ取得することができます。
両者の違いについては、下記の比較表にまとめました
SINGLE | 比較内容 | UP TO 1 ROWS |
---|---|---|
最初にヒットした1件 | 取得方法 | 全レコードを確認して条件に合う最初の1件 |
高い | パフォーマンス | 低い |
少ない | バッファ使用量 | 多い |
全て含む場合に使用 | 検索条件に主キー(推奨) | 一部のみの場合に使用 |
保証されている(マスタなど) | データの存在(推奨) | 保証されていない |
(推奨)は、基本的な考え方の一例です。
テーブルの名称を静的に指定する(AS)
SELECT col1 col2 INTO table itab FROM spfli1 AS s1 JOIN spfli2 AS s2 ON s1~col1 = s2~col2.
全ての列を取得する(*)
全件取得する必要がない限りは個別に項目を指定する事をオススメします。
SELECT * INTO wa FROM spfli.
列の最大値を取得する(MAX)
SELECT MAX(col) INTO wa FROM spfli.
列の最小値を取得する(MIN)
SELECT MIN(col) INTO wa FROM spfli.
列の平均を取得する(AVG)
SELECT AVG(col) INTO wa FROM spfli.
値または行のカウントを取得する(COUNT)
SELECT COUNT(*) INTO wa FROM spfli.
参照資料: