EAVモデルにおける同一会員・項目の最新値抽出(MAX関数による行番号指定)

EAV(エンティティ・属性・値)形式の縦持ちテーブルから、同一会員・同一項目の最新値を取り出して横持ち表示する集約SQLに関する問題です。 副問合せの絞り込み: 条件(3)「同一会員番号で同一項目名の行が複数ある場合、より大きい行番号の項目値を採用する」より、副問合せ `WHERE 行番号 IN (SELECT a(行番号) FROM 会員項目 GROUP BY 会員番号, 項目名)` では、グループごとの最大の行番号を特定する必要があります。したがって、ここには集約関数 `MAX` が入ります。 外側問合せの横持ち集約: 主問合せでは `GROUP BY 会員番号` によって1会員につき1行にまとめます。CASE式で該当する項目名の値を取り出し、それ以外の行(NULL)と集約して単一の非NULL値を取得するため、ここでも `MAX` 集約関数を使用します。 以上より、すべての空欄〔  a  〕には `MAX` が入るため、ウ が正解です。 COUNT は行数を数える関数であり、最大行番号の特定や文字列項目値の集約には使用できません。 DISTINCT は重複を除去する修飾子であり、副問合せの集約演算やSELECT句の関数呼び出し構文には適合しません。 MIN を用いると最小の行番号(最も古い履歴)が選択されてしまい、条件(3)の「より大きい行番号を採用する」要件を満たせなくなります。

ある電子商取引サイトでは,会員の属性を柔軟に変更できるように,“会員項目” 表で管理することにした。“会員項目” 表に対し,次の条件でSQL文を実行して結果を得る場合,SQL文の〔  a  〕に入れる字句はどれか。ここで,実線の下線は主キーを,NULLは値がないことを表す。

〔条件〕

  1. (1)

    同一 “会員番号” をもつ複数の行によって,一人の会員の属性を表す。

  2. (2)

    新規に追加する行の行番号は,最後に追加された行の行番号に 1 を加えた値とする。

  3. (3)

    同一 “会員番号” で同一 “項目名” の行が複数ある場合,より大きい行番号の項目値を採用する。

会員項目

行番号

会員番号

項目名

項目値

1

0111

会員名

情報太郎

2

0111

最終購入年月日

2019-02-05

3

0112

会員名

情報花子

4

0112

最終購入年月日

2019-01-30

5

0112

最終購入年月日

2019-02-01

6

0113

会員名

情報次郎

〔結果〕

会員番号

会員名

最終購入年月日

0111

情報太郎

2019-02-05

0112

情報花子

2019-02-01

0113

情報次郎

NULL

〔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年春期 午前Ⅱ
ア
COUNT
イ
DISTINCT
ウ
MAX
エ
MIN