Oracle SQL SELECT6 : SELECT文のWHERE句でのEXISTS演算子


おすすめ書籍



EXISTS演算子の使い方

副問合せにキー値が指定されたクエリーによるデータが返されるもののみにしたい場合に、 WHERE句の中でEXISTS演算子を使い、EXISTSのクエリーは、主となるテーブルから1個以上の列に依存する副クエリーとなります。

言葉の説明ではよく分からないので、実際の例を示します。以下のSQL文は 「等結合」 で使用したものですが、これをEXISTSを使ったSQLに変えてみます。

SQL> SELECT TU.売上番号,TU.明細番号,TU.商品コード,
  2         TS.商品名,TS.売上単価,TU.売上数量,TS.売上単価 * TU.売上数量 AS 金額
  3  FROM TT_売上明細 TU , TM_商品 TS
  4  WHERE TU.商品コード = TS.商品コード;

この例では、FROM句にTT_売上明細、TM_商品を宣言し、WHERE句での連結を行っています。
FROM句からTM_商品を外してWHERE句のEXISTS演算子の副クエリーの中でTT_売上明細、TM_商品の連結を行い 更に、商品名での絞込を行うSQLが以下の様になります。

EXISTS演算子の副クエリーでレコードが返される場合に、条件が合致したことになり、 その時のTT_売上明細のレコードがSELECT対象になります。 尚、売上番号での範囲もBETWEENで絞ってAND条件にしています。

SQL> SELECT TU.売上番号,TU.明細番号,TU.商品コード,TU.売上数量
  2  FROM TT_売上明細 TU
  3  WHERE TU.売上番号 BETWEEN 1 AND 2
  4  AND   EXISTS (
  5          SELECT '1' FROM TM_商品 TS
  6          WHERE TU.商品コード = TS.商品コード
  7          AND   TS.商品名 LIKE 'PC-900%'
  8        );

  売上番号   明細番号 商品コード   売上数量
---------- ---------- ---------- ----------
         1          1          1          2
         2          1          2          1

この例ではFROM句にTM_商品を宣言していないため、SELECT句の中にはTT_売上明細の列しか宣言できない様になります。 TM_商品の列も表示する場合には、最初のSQLに条件を追加した方がいいのですが、敢えてEXISTSの例として示していますので、その点は悪しからず。

それでは商品名を表示する様に、SELECT句の中に副クエリーで商品名を抽出する様にしてみます。

SQL> SELECT TU.売上番号,TU.明細番号,TU.商品コード,TU.売上数量
  2        ,(
  3          SELECT MS.商品名
  4          FROM TM_商品 MS
  5          WHERE TU.商品コード = MS.商品コード
  6         ) AS 商品名
  7  FROM TT_売上明細 TU
  8  WHERE TU.売上番号 BETWEEN 1 AND 2
  9  AND   EXISTS (
 10          SELECT '1' FROM TM_商品 TS
 11          WHERE TU.商品コード = TS.商品コード
 12          AND   TS.商品名 LIKE 'PC-900%'
 13        );

  売上番号   明細番号 商品コード   売上数量 商品名
---------- ---------- ---------- ---------- ----------------------------------------------------------------
         1          1          1          2 PC-9001
         2          1          2          1 PC-9002


NOT EXISTS演算子の使い方

NOT EXISTS演算子 とは EXISTS演算子 の否定形で、 副クエリーから何もレコードが返されない場合に条件がTRUEとなります。 上記のEXISTS演算子の例にNOTを付加してみます。

SQL> SELECT TU.売上番号,TU.明細番号,TU.商品コード,TU.売上数量
  2        ,(
  3          SELECT MS.商品名
  4          FROM TM_商品 MS
  5          WHERE TU.商品コード = MS.商品コード
  6         ) AS 商品名
  7  FROM TT_売上明細 TU
  8  WHERE TU.売上番号 BETWEEN 1 AND 2
  9  AND   NOT EXISTS (
 10          SELECT '1' FROM TM_商品 TS
 11          WHERE TU.商品コード = TS.商品コード
 12          AND   TS.商品名 LIKE 'PC-900%'
 13        )
 14  ORDER BY TU.売上番号,TU.明細番号;

  売上番号   明細番号 商品コード   売上数量 商品名
---------- ---------- ---------- ---------- ----------------------------------------------------------------
         1          2          4          1 NOTE-1010
         2          2          5          2 NOTE-1020
         2          3         11          1 HUB-A001

SQLの結果として、売上番号が1~2で、かつ商品名の先頭から「PC-900」を含まないTT_売上明細のレコードが表示されています。





ページのトップへ戻る