応用情報技術者試験 令和5年秋期 問29
“製品”表と”在庫”表に対し,次のSQL文を実行した結果として得られる表の行数は幾つか。
SELECT DISTINCT 製品番号
FROM 製品
WHERE NOT EXISTS (
SELECT 製品番号
FROM 在庫
WHERE 在庫数 > 30 AND 製品.製品番号 = 在庫.製品番号
)ア:1 イ:2 ウ:3 エ:4
出典 IPA公開[過去問題]:https://www.ipa.go.jp/shiken/mondai-kaiotu/ps6vr70000010d6y-att/2023r05a_ap_am_qs.pdf
SQL系の問題を解くポイントはSQLを実行した際のイメージを持てるかどうかです。SQL系の問題はパターンが多くありますし、世の中のエンジニア系の求人にも「SQL」が記載されているのでしっかり実行後のイメージを持てるようにスキルを身に付けた方がいいでしょう。
さて、この問題のように副問い合わせ(WHEREの条件に別のSQLの実行結果を使う方法)を使っているケースでは( )内のSQLから考えましょう。
(
SELECT 製品番号
FROM 在庫
WHERE 在庫数 > 30 AND 製品.製品番号 = 在庫.製品番号
)
となっていますが、WHEREでの条件の後半は製品表と在庫表を結合する処理なので、今は置いておきます。まずは在庫表から在庫数が30よりも多い製品番号だけ取り出します。取り出された製品番号は「CC5001・ZZ9900・AB1805・CC5001」の4つとなりました。
先ほどのWHEREの条件の後半にあった「製品.製品番号 = 在庫.製品番号」で製品表と在庫表の製品番号を結合します。そうすると4件のレコードが結合されました。
そうすると、答えは「エ:4」と思うかもしれませんが、外側のSQLのWHEREには「NOT EXSITS」と書かれていました。本来EXSITSは( )内のSQLの結果が1件でもあれば外側のSQLを実行するという処理を行います。しかし、この問題のように( )内のSQLで結合が行われると結合したレコードを出力します。ただ、今回は「NOT」がついているので、結合したレコード(AB1805・CC5001・ZZ9900)以外の製品番号(MZ1000・XZ3000の2行)が出力されるので正解は「イ:2」となります。
※「DISTINCT 列名」を使うと、指定した列で重複データがある場合は1つにまとめます。例えば「SELECT DISTINCT 製品番号 FROM 在庫」を実行した場合は重複しているCC5001が1つまとめられるので(CC5001・ZZ9900・AB1805)の3件のレコードが出力されます。