EXISTS述語を使った相関副問い合わせ

スポンサードリンク

副問い合わせの中に相関副問い合わせという方法がある。これは、主問い合わせの結果をチェックするというものである。

副問い合わせではWHERE句で指定されたSELECT文の実行結果を元に主問い合わせを実行した。

それに対して、相関副問い合わせでは主問い合わせの表の1行ごとに副問い合わせを実行する。

そして、EXISTSを指定された副問い合わせでは、主問い合わせで指定されたデータが存在すれば真を返し、存在しなければ偽を返す。真の行だけが抽出される。

まず、準備としてEXISTS述語を指定したSELECT文の実行結果が分かりやすいように商品表に次の2つの行を追加する。

商品表

EXISTS述語の記述形式は以下のとおりである。

<< 記述形式 >>

EXISTS述語の記述形式

EXISTSの記述形式を見ても分かるように、主問い合わせのWHERE句にEXISTSを指定する。

《例題1》

売上のあった商品名を抽出する。売上のあった商品とは、売上明細に存在する商品のことである。つまり、商品表の商品のうち売上明細に存在する商品を抽出すればよいのである。

売上明細表と商品表

SELECT文

SELECT 商品CD,商品名
FROM 商品表
WHERE EXISTS
(SELECT * FROM 売上明細 WHERE 売上明細.商品CD = 商品表.商品CD)

− 実行結果 −

実行結果

売上明細に存在する商品CDと商品名が抽出されている。商品CDが70の手帳と、商品CDが80のホッチキスは売上明細に存在しないので抽出されない。

EXISTSを指定したときは、主問い合わせから実行されるのが今までの副問い合わせと大きく違うところである。

Point

EXISTSが指定されたときは、主問い合わせから実行される。

例題のSELECT文は次のように実行される。
まず主問い合わせの「SELECT 商品CD,商品名 FROM 商品表」を実行する。

− 主問い合わせの実行結果 −

主問い合わせの実行結果

1行目について、副問い合わせ(SELECT * FROM 売上明細 WHERE 売上明細.商品CD = 商品表.商品CD)を実行し、一致する行があるかどうかをチェックする。 この場合は、1行目の商品CDの値は"10"であるから、SELECT * FROM 売上明細 WHERE 売上明細.商品CD = 10を実行する。一致する行が存在するので真が返さ れ、表示される。

1行目の実行結果

同様にして、2行目以降も実行する。新しく追加した商品CDが70の手帳と、商品CDが80のホッチキスは、売上明細に存在しないので抽出されない。
EXISTS述語を指定すると、副問い合わせで主問い合わせとは別の表を指定し、チェックすることができる。これを相関副問い合わせという。
これとは逆に、存在しないときを真にするときは、NOT EXISTSを指定する。例題2は、NOT EXISTSを使って商品表より売上の無かった商品を抽出するSELECT文である。

《例題2》

売上のなかった商品CDと商品名を抽出する。

SELECT文

SELECT 商品CD,商品名
FROM 商品表
WHERE NOT EXISTS
(SELECT * FROM 売上明細 WHERE 売上明細.商品CD = 商品表.商品CD)

− 実行結果 −

実行結果

実行の順序はEXISTSのときと同じである。NOT EXISTSを指定しているので、例題2の実行結果と逆の結果になっている。これは、副問い合わせで行が抽出されたときに「偽」を返し、行が抽出されなかときは、「真」を返すからである。