SkillStack
テクノロジ系10 / 25問

データベーススペシャリスト試験 令和3年度 秋期 午前II 問10

ある電子商取引サイトでは、会員の属性を柔軟に変更できるように、"会員項目"表で管理することにした。"会員項目"表に対し、次の条件でSQL文を実行して結果を得る場合、SQL文の「a」に入れる字句はどれか。ここで、実線の下線は主キーを、NULLは値がないことを表す。 〔条件〕 (1) 同一"会員番号"をもつ複数の行によって、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 会員番号

データベーススペシャリスト試験 令和3年度 秋期 午前II 問10の図表

選択肢を押すと答え合わせができます。

正解と解説を見る

【正解】ウ

同じ会員番号と項目名をもつ行が複数ある場合、最後に追加された行、すなわち最大の行番号をもつ行を採用する必要があります。そのため、内側の副問合せでは、会員番号と項目名ごとにGROUP BYし、MAX(行番号)で最大の行番号を求めます。

画像のデータでは、会員番号0112の「最終購入年月日」は行番号4と5にあります。MAX(行番号)はMAX(4、5)=5となるので、行番号5の2021-02-01が採用されます。副問合せ全体では行番号1、2、3、5、6が残ります。

外側では、CASE式によって対象の項目名に対応する項目値だけを返し、それ以外の行ではNULLを返します。会員番号ごとにまとめた後、MAXでNULL以外の値を一つ取り出すことで、会員名と最終購入年月日を別々の列に変換できます。0113には最終購入年月日の行がないため、CASE式は全てNULLとなり、MAXの結果もNULLです。したがって、三つの「a」にはいずれもMAXが入り、ウが正解です。

アのCOUNTは誤りです。COUNTは行数又はNULL以外の値の個数を数える集約関数であり、最大の行番号や項目値そのものを取得する関数ではありません。

イのDISTINCTは誤りです。DISTINCTは重複する行や値を取り除く指定であり、最新の行を選ぶ機能はありません。また、この位置で項目値を一つに集約する関数としては使用できません。

エのMINは誤りです。MIN(行番号)では最初に追加された行を選びます。0112では行番号4が選ばれ、最終購入年月日が2021-01-30となるため、期待する結果と一致しません。

【ポイント】 MAX(行番号)とGROUP BYを組み合わせると、グループごとの最新行を特定できます。 CASE式と集約関数の組合せは、行として格納された項目を列へ変換する条件付き集約の定石です。

出典:令和3年度 秋期 データベーススペシャリスト試験 午前II 問10
※ 解説は SkillStack 編集部が作成したものです。Web 表示のため、図表の配置や表記を一部改めています。

この回の25問を、アプリで通しで解く

  • 本番と同じ問題数・制限時間で通し演習(模試モード)
  • 間違えた問題は自動で「復習すべき問題」に回る
  • 解説で分からない点はAIに質問できる
SkillStackで無料で始める