IPA過去問ドリル

平成31年度 春期 データベーススペシャリスト試験 午前Ⅱ 問14

テクノロジ/データベース

ある電子商取引サイトでは,会員の属性を柔軟に変更できるように,“会員項目”表で管理することにした。“会員項目”表に対し,次の条件でSQL文を実行して結果を得る場合,SQL文のaに入れる字句はどれか。ここで,実線の下線は主キーを表し,NULLは値がないことを表す。 〔条件〕 (1) 同一“会員番号”をもつ複数の行によって,一人の会員の属性を表す。 (2) 新規に追加する行の行番号は,最後に追加された行の行番号に1を加えた値とする。 (3) 同一“会員番号”で同一“項目名”の行が複数ある場合,より大きい行番号の項目値を採用する。 〔SQL文〕 SELECT 会員番号, [ a ](CASE WHEN 項目名='会員名' THEN 項目値 END) AS 会員名, [ a ](CASE WHEN 項目名='最終購入年月日' THEN 項目値 END) AS 最終購入年月日 FROM ( SELECT 会員番号, 項目名, 項目値 FROM 会員項目 WHERE 行番号 IN ( SELECT [ a ](行番号) FROM 会員項目 GROUP BY 会員番号, 項目名 ) ) T GROUP BY 会員番号 ORDER BY 会員番号

平成31年度 春期 データベーススペシャリスト試験 午前Ⅱ 問14の図

出典:平成31年度 春期 データベーススペシャリスト試験 午前Ⅱ 問14

正解:ウ

解説

“会員項目”表では,同一の会員番号・項目名の行が複数存在する場合,条件(3)により,より大きい行番号(つまり最後に更新された値)の項目値を採用する必要があります。サブクエリでは,会員番号・項目名でグループ化した上で行番号の最大値をMAXで求め,その行番号に一致する行だけをWHERE 行番号 IN (...)で絞り込みます。これにより,各会員・各項目について最新(最大行番号)の1行だけが残ります。その上で,外側のクエリでは項目名が“会員名”又は“最終購入年月日”である行の項目値を,CASE式とMAX関数(GROUP BY会員番号でグループ化された1行の中から該当する項目値を取り出す)によってピボットし,会員ごとに1行の結果にまとめています。

選択肢ごとの解説

  • 誤り。COUNTは行数を数える関数であり,最新の行番号を求めたり,CASE式で絞り込んだ項目値を取り出したりする用途には使えません。
  • 誤り。DISTINCTは重複行を除去する修飾子であり,最大の行番号を求めるサブクエリにも,CASE式の結果から値を1つ取り出す集約にも使用できません。
  • 正しい。サブクエリのMAX(行番号)によって会員番号・項目名ごとに最新(最大)の行番号を求めて絞り込み,外側のクエリのMAX(CASE ...)によってグループ化後の該当する項目値を取り出すことで,条件(2)(3)を満たす結果が得られます。
  • 誤り。MINでは最小の行番号(最も古い値)が採用されてしまい,条件(3)の「より大きい行番号の項目値を採用する」という要件に反します。
データベーススペシャリストの過去問を演習モードで解く