InterBase クイック スタート:Part IV - サブクエリの利用

提供: InterBase

InterBase クイック スタート:Part IV - データの抽出 へ戻る

サブクエリは、WHERE 句の特別なケースです。

WHERE 句では、列名、比較演算子、値を指定していました。 WHERE は、演算子を使用して、値に対して列の内容をテストします。 WHERE 句の、この値の部分の代わりに、SELECT 文を使用することができます。 この内部 SELECT 句が、サブクエリ です。 InterBase では、SELECT サブクエリを実行し、その結果セットを WHERE 句の値として使用します。

たとえば、ID が 144 の特定の社員と同じ国で働いている社員のリストを抽出するとしましょう。 サブクエリを使用しなければ、2 つのクエリを実行する必要があります:

  1. この社員がどの国で働いているか検索します:
    SELECT job_country
    FROM   Employee
    WHERE  emp_no = 144
    

    このクエリは USA を返します。

  2. そして今度は 2 つ目のクエリを実行し、USA にいる社員のリストを検索します:
    SELECT emp_no,
           last_name
    FROM   Employee
    WHERE  job_country = 'USA'
    

Image 025.jpg 1 つの項目の検索にサブクエリを使用する

サブクエリにより、上記の 2 つのクエリを、1 つの文で行うことができます。 次のクエリは、上記の組み合わせです:

SELECT emp_no,
       last_name
FROM   Employee
WHERE  job_country = (SELECT job_country
                      FROM   Employee
                      WHERE  emp_no = 144)

この場合、サブクエリは 1 つの値、USA を抽出します。 メインのクエリは、USAWHERE 句でテストされる値として解釈します。 WHERE 句が単一の値をテストするため({{{1}}} で)、サブクエリは単一の値を返さなければなりません。そうではない場合、文はエラーを生成します。

このクエリの結果は、33 名の社員番号と姓のリストとなります。 これらは、社員番号 144 と同じ国で働いている社員です。

Image 025.jpg 複数の項目の検索にサブクエリを使用する

サブクエリが複数の値を返す場合、サブクエリを含んでいる WHERE 句は、複数の値に対してテストを行う演算子を使用していなければなりません。 IN がそのような演算子の 1 つです。

次の文を実行して、部署 623 にいる者と同じ額の給与をもらっているすべての社員の、姓と部署番号を抽出します。 ここでは、部署 623 にいる社員のすべての給与を返す、サブクエリを使用します。 メイン クエリは、各社員を順番に選択し、それに関連付けられている給与が、サブクエリの結果セット内にあるかどうかをチェックしていきます。

 
SELECT last_name,
       dept_no
FROM   Employee
WHERE  salary IN (SELECT salary
                  FROM   Employee
                  WHERE  dept_no = 623)

結果はこのようになります:

TutorialSubquery1.png

サブクエリのための条件

次の表は、演算子の左にある値を、演算子の右にあるサブクエリの結果と比較する演算子をまとめたものです:

演算子

用途

All

サブクエリが返した値すべてについて、比較が true だった場合に、true を返します。

ANY または SOME

サブクエリが返した値のうち、1 つでも比較が true だった場合に、true を返します。

EXISTS

サブクエリが返した結果セット内に、ある値が 1 つでも存在するかどうかを、判断します。

SINGULAR

サブクエリが返した結果セット内に、厳密にある値が存在するかどうかを、判断します。

Image 025.jpg ALL を使用する

IN 演算子は、値のリストとの等価性のみをテストします。 等価性以外の関係をテストしたい場合には、ALL を使用することができます。 たとえば、部署 623 の社員よりも高い給与の者を検索するには、次のクエリを入力します:

SELECT last_name,
       salary
FROM   Employee
WHERE  salary > ALL (SELECT salary
                     FROM   Employee
                     WHERE  dept_no = 623)

結果はこのようになります:

TutorialSubquery2.png

この文では、サブクエリ内のすべての値に対してテストを行い、給与がより大きかった行を抽出しています。 部署 623 のマネージャはこのクエリを使用して、どのグループの社員が、自分のところの社員よりも所得を得ているか確認することができます。

Image 025.jpg ANY、EXISTS、SINGULAR を使用する

サブクエリから返されるすべての値に対してテストするのではなく、最低 1 つの値に対してテストするように、前の文を書き換えてみます:

SELECT last_name,
       salary
FROM   Employee
WHERE  salary > ANY (SELECT salary
                     FROM   Employee
                     WHERE  dept_no = 623)

この文は、salary がサブクエリからの値のいずれかより大きかった行を抽出します。 ANY キーワードには、同義語 SOME があります。 この 2 つは入れ替え可能です。

他の 2 つのサブクエリ演算子は、EXISTSSINGULAR です。

  • 指定された値に対し、EXISTS は、少なくとも 1 つの識別された行が、サブクエリで指定される検索条件を満たしているかどうかをテストします。 EXISTS は、NULL 値を処理している際でも、true または false を返します。
  • 指定された値に対し、SINGULAR は、厳密に、ある 1 つの識別された行が、サブクエリで指定される検索条件を満たしているかどうかをテストします。

次は: