基本情報技術者 2019年 秋期 午前(科目A) 問26
問題文
“得点”表から、学生ごとに全科目の点数の平均を算出し、平均が80点以上の学生の学生番号とその平均点を求める。aに入れる適切な字句はどれか。ここで、実線の下線は主キーを表す。
得点(学生番号, 科目, 点数)
〔SQL文〕
SELECT 学生番号, AVG(点数) FROM 得点 GROUP BY [ a ]
選択肢
ア:科目 HAVING AVG(点数) >= 80
イ:科目 WHERE 点数 >= 80
ウ:学生番号 HAVING AVG(点数) >= 80(正解)
エ:学生番号 WHERE 点数 >= 80
平均が80点以上の学生を抽出するSQLの穴埋め【午前2 解説】
要点まとめ
- 結論: 学生ごとに GROUP BY 学生番号 で集計し HAVING AVG(点数) >= 80 を指定して平均80点以上を抽出します。
- 根拠: WHERE は行フィルタ、HAVING は集計後のフィルタであり、平均などの集計関数は HAVING で評価します。
- 差がつくポイント: GROUP BY に何を指定するかで「学生ごとの平均」か「科目ごとの平均」かが決まる点に注意してください。
正解の理由
SELECT 学生番号, AVG(点数) FROM 得点 GROUP BY 学生番号 HAVING AVG(点数) >= 80 の形にすることで、まず学生番号ごとに点数を集計(AVG)し、集計結果に対して平均が80以上かを判定します。HAVING は集計結果に対する条件指定に使うため、AVG(点数) のような集計関数を用いる条件は WHERE ではなく HAVING で指定する必要があります。
よくある誤解
- WHERE と HAVING を混同し、AVG(点数) >= 80 を WHERE に書いてしまう。WHERE は集計前の行フィルタで集計関数は使えません。
- GROUP BY に「科目」を指定してしまい、学生ごとの平均ではなく科目ごとの平均を求めてしまうミス。
- HAVING を使えば何でも絞り込めると考え、GROUP BY を忘れてしまう。GROUP BY がないと「学生ごとの」集計になりません(DBMS による挙動差に注意)。
解法ステップ
- 問題意図を確認:学生ごとに全科目の平均を求め、平均が80点以上の学生を列挙する。
- 学生ごとの集計には GROUP BY 学生番号 を用いると判断する。
- 集計結果(AVG(点数))に条件を付けるには HAVING を使う必要があると判定する。
- 以上より [a] に入るべき語句は「学生番号 HAVING AVG(点数) >= 80」となる。
選択肢別の誤答解説
- ア: 科目 HAVING AVG(点数) >= 80
- 誤り。HAVING の使い方は正しいが GROUP BY が「科目」になるため、科目ごとの平均が求まってしまい学生ごとの平均ではない。
- イ: 科目 WHERE 点数 >= 80
- 誤り。WHERE は集計前の行フィルタであり、また問題の意図(学生ごとの平均)を満たさない。さらにこの位置(GROUP BY の後)に WHERE を置くのは文法的に不適切。
- ウ: 学生番号 HAVING AVG(点数) >= 80
- 正解。学生番号ごとに AVG(点数) を計算し、HAVING でその平均が 80 以上のグループを抽出する。
- エ: 学生番号 WHERE 点数 >= 80
- 誤り。GROUP BY 学生番号 は正しいが WHERE 点数 >= 80 は集計関数を使った条件を表現できず、意図する「平均が80以上」を満たせない。また文法的順序の観点でも誤用。
補足コラム
- 実際のSQL例:
SELECT 学生番号, AVG(点数) AS 平均点 FROM 得点 GROUP BY 学生番号 HAVING AVG(点数) >= 80;
- HAVING と WHERE の使い分け:WHERE は各行に対する条件(集計前)、HAVING はグループに対する条件(集計後)です。AVG, SUM, COUNT などの集計関数を条件に使う場合は HAVING を選びます。
- DBMS によっては HAVING を GROUP BY なしで使うと全体を1グループとして扱う場合がありますが、明示的に GROUP BY を書く方が可読性・移植性が高いです。
FAQ
Q1: AVG(点数) >= 80 を WHERE に書くと何が起きますか?
A1: 標準SQLでは文法エラーになります。WHERE は集計前の行に対するフィルタで集計関数を直接評価できません。
A1: 標準SQLでは文法エラーになります。WHERE は集計前の行に対するフィルタで集計関数を直接評価できません。
Q2: GROUP BY を書かずに HAVING だけで同様の結果を得られますか?
A2: DBMS に依存します。標準では GROUP BY なしの HAVING は全行を1グループとして扱う場合がありますが、「学生ごと」に分けて集計する意図がある場合は必ず GROUP BY 学生番号 を明示してください。
A2: DBMS に依存します。標準では GROUP BY なしの HAVING は全行を1グループとして扱う場合がありますが、「学生ごと」に分けて集計する意図がある場合は必ず GROUP BY 学生番号 を明示してください。
Q3: 性能面で気を付けることはありますか?
A3: 大量のデータで集計を行う場合、適切なインデックス(学生番号など)や集計用の事前計算(マテリアライズドビュー、集約テーブル)を検討すると良いです。
A3: 大量のデータで集計を行う場合、適切なインデックス(学生番号など)や集計用の事前計算(マテリアライズドビュー、集約テーブル)を検討すると良いです。
関連キーワード: SQL、GROUP BY、HAVING、WHERE、AVG、集計関数、平均点、学生番号、SELECT、データ集計

\ せっかくなら /
基本情報技術者を
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

