データベースの基礎
社員表(社員番号, 部署, 給与)から、部署ごとの平均給与が300以上の部署と、その平均給与を求めたい。正しいSQL文はどれか。
- ASELECT 部署, AVG(給与) FROM 社員 GROUP BY 部署 HAVING AVG(給与) >= 300
- BSELECT 部署, AVG(給与) FROM 社員 WHERE AVG(給与) >= 300 GROUP BY 部署
- 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未満の部署も結果に出てきます。