[第3回]国家試験解説[AP令和5年秋]

応用情報技術者試験 令和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件のレコードが出力されます。