副照会

一時的な表の情報を基に検索条件を絞る必要があるときは、 副照会を使用できます。 例えば、ある表の中の従業員で、2 番目の表にも存在して 特定のプロジェクトに関与していることが示されている、 すべての従業員番号を知りたい場合などに便利です。

副照会の概念

特定プロジェクト (プロジェクト番号が MA2111) に従事するすべての従業員の従業員番号、名前、 および歩合給のリストが必要であるとします。 この SELECT ステートメントの初めの部分は容易に コーディングできます。
SELECT EMPNO, LASTNAME, COMM
  FROM DSN8D10.EMP
  WHERE EMPNO
  ⋮

ただし、 DSN8D10. EMP テーブルにはプロジェクト番号データが含まれていないため、続行できません。 DSN8D10. EMPPROJACT テーブルに対して別の SELECT ステートメントを発行しなければ、どの従業員がプロジェクト MA2111 に取り組んでいるかはわかりません。

この問題を解決するために副照会を使用でき ます。 副照会 は、WHERE 文節内の副選択または全選択 です。 副照会を囲む SELECT ステートメントを外部 SELECT と呼びます。
SELECT EMPNO, LASTNAME, COMM
  FROM DSN8D10.EMP
  WHERE EMPNO IN
    (SELECT EMPNO
       FROM DSN8D10.EMPPROJACT
        WHERE PROJNO = 'MA2111');
このSQLステートメントの結果をよりよく理解するためにDb2次のプロセスを経ることを想像してください。
  1. Db2 は、副照会を評価して、 EMPNO 値のリストを取得します。
    (SELECT EMPNO
       FROM DSN8D10.EMPPROJACT
       WHERE PROJNO = 'MA2111');
    この結果は、中間的な結果表にあって、 次の出力のようになります。
    from EMPNO 
         =====
         200
         200
         220 
  2. その後で、この中間的な結果表は、外部 SELECT の検索条件のリストとなります。 実は、Db2 は次のステートメントを実行します。
    SELECT EMPNO, LASTNAME, COMM
      FROM DSN8D10.EMP
      WHERE EMPNO IN
      ('000200', '000220');
    したがって、結果表は、以下の出力のようになります。
    EMPNO   LASTNAME  COMM
    ======  ========  ====
    000200  BROWN     2217
    000220  LUTZ      2387

相関および非相関副照会

副照会は、行 (WHERE 文節の) または行グループ (HAVING 文節の) を限定するのに必要な 情報を提供します。 副照会は、ある結果表を作成します。その結果表を使って行または照会された行グループを限定します。

各行または行グループごとに副照会の内容が同じ場合は、副照会は一度だけ実行します。 このような副照会は、一度限り実行される照会を意味する非相関副照会 と呼ばれます。 たとえば、次のステートメントでは、サブクエリの内容はテーブル DSN8D10. EMP のすべての行に対して同じです。
SELECT EMPNO, LASTNAME, COMM
  FROM DSN8D10.EMP
  WHERE EMPNO IN
    (SELECT EMPNO
       FROM DSN8D10.EMPPROJACT
        WHERE PROJNO = 'MA2111');

行ごとにあるいは行グループごとに照会内容が異なる副照会のこと を相関副照会 と呼びます。 関連サブクエリの詳細については、「関連サブクエリ」 を参照してください。

副照会と述部

述部 は、特定の行またはグループに関して真、偽、または不明の条件を指定する検索条件の要素です。 副照会は、別の SQL ステートメントの WHERE 文節または HAVING 文節内にある SELECT ステートメントで、これは常に述部に含まれます。 述部の形式は以下のとおりです。
operand operator (subquery)
WHERE または HAVING 文節には、副照会を含む述部を含めることができます。 副照会を含んでいる述部は、他の検索述部と同様に、括弧で囲むことができ、 その頭に NOT キーワードを付けることができ、 さらにキーワード AND と OR で他の述部と連結することもできます。 例えば、照会の WHERE 文節は、次の文節のようになります。
WHERE X IN (subquery1) AND (Y > SOME (subquery2) OR Z IS NULL)

副照会は他の副照会の述部に置くこともできます。 そのような副照会は、あるネスト・レベルで ネストしていると呼びます。 例えば、外部SELECT内のサブクエリ内のサブクエリは、入れ子レベルが2です。 Db2 ネストレベルを15まで許可していますが、ネストレベルが1より大きいことを要求するクエリはほとんどありません。

ある副照会とその外部 SELECT との関係は、 その副照会と、その内側にネストされている別の副照会との関係と同じであり、 特に断りがない限り、同じ規則が適用されます。

副照会の結果表

副照会は、比較演算子の左側にある列数と同じ数の列を持つ結果表を 作成する必要があります。 例えば、以下の SELECT ステートメントはどちらも有効です。
SELECT EMPNO, LASTNAME 
  FROM DSN8D10.EMP
  WHERE SALARY =
  (SELECT AVG(SALARY) 
    FROM DSN8D10.EMP);
SELECT EMPNO, LASTNAME 
  FROM DSN8D10.EMP
  WHERE (SALARY, BONUS) IN
  (SELECT AVG(SALARY), AVG(BONUS) 
    FROM DSN8D10.EMP);

基本述部の副照会の場合を除き、結果表には複数の行を含めることができます。 詳細は、「サブクエリを挿入できる場所」 を参照してください。