データベースの基礎

社員表(社員番号, 部署, 給与)から、部署ごとの平均給与が300以上の部署と、その平均給与を求めたい。正しいSQL文はどれか。

  1. ASELECT 部署, AVG(給与) FROM 社員 GROUP BY 部署 HAVING AVG(給与) >= 300
  2. BSELECT 部署, AVG(給与) FROM 社員 WHERE AVG(給与) >= 300 GROUP BY 部署
  3. CSELECT 部署, AVG(給与) FROM 社員 WHERE 給与 >= 300 GROUP BY 部署
答えと解説を見る

正解:A. SELECT 部署, AVG(給与) FROM 社員 GROUP BY 部署 HAVING AVG(給与) >= 300

SQLの処理は、FROMの表から WHERE で行を選び、GROUP BY でグループにまとめ、HAVING でグループを選ぶ、という順に考えます。WHEREは1行ずつに対する条件で、グループにまとめる前に評価されるので、AVGのような集約関数は書けません。グループごとの集計結果に対する条件は HAVING に書くので、HAVING AVG(給与) >= 300 が正しい書き方です。WHERE 給与 >= 300 とすると、給与が300以上の社員だけを先に選んでから平均するので、「給与が300以上の社員だけの平均」という別の意味になり、部署全体の平均給与が300未満の部署も、給与が300以上の社員が1人でもいれば結果に出てきます。

  • A. 正しい。グループごとの集計結果に対する条件は、HAVING句に書きます。
  • B. WHERE句には集約関数を書けないので、この文はエラーになります。
  • C. 給与が300以上の社員だけで平均を取るので、部署全体の平均給与が300未満の部署も結果に出てきます。
この分野を解く 分野ページへ

関連する計算ツール

データベースの基礎の参考書を探す PR

Amazonの検索結果へのリンクです。Amazonのアソシエイトとして、半導体教室は適格販売により収入を得ています。

データベースの基礎のほかの問題

  1. 売上表(店舗, 金額)に、(A, 500)、(A, 700)、(B, 300)、(B, 400)、(C, 1200)、(D, 200)、(D, 900) の7行がある。SELECT 店舗, SUM(金額) FROM 売上 GROUP BY 店舗 HAVING SUM(金額) >= 1000 の結果は何行になるか。
  2. 社員表(氏名, 部署, 給与)に8行あり、部署ごとの給与は、営業が320、280、350、開発が400、310、総務が260、300、企画が330である。SELECT 部署, COUNT(*) FROM 社員 WHERE 給与 >= 300 GROUP BY 部署 HAVING COUNT(*) >= 2 の結果は何行になるか。
  3. 社員表(社員番号, 氏名, 部署ID)に4行あり、部署IDは順に10、20、10、NULLである。部署表(部署ID, 部署名)には部署IDが10、20、30の3行がある。SELECT 社員.氏名, 部署.部署名 FROM 社員 INNER JOIN 部署 ON 社員.部署ID = 部署.部署ID の結果は何行になるか。
  4. 社員表(社員番号, 氏名, 部署ID)に5行あり、部署IDは順に10、20、10、NULL、NULLである。部署表(部署ID, 部署名)には部署IDが10、20、30の3行がある。SELECT 部署.部署名, 社員.氏名 FROM 部署 LEFT OUTER JOIN 社員 ON 部署.部署ID = 社員.部署ID の結果は何行になるか。
  5. 表Rの列xの値は 1、1、2、3 の4行、表Sの列xの値は 1、1、2、4 の4行である。SELECT * FROM R INNER JOIN S ON R.x = S.x の結果は何行になるか。