どうも!ひよこSE(@PiyoOct)です。
基本情報技術者試験のデータベースを勉強していると、”HAVING”やら、”WHERE”を見かけて。
「WHERE句は条件のしぼりこみをしてくれる。ん?HAVING句も?ちがいがよくわからん(´▽`*)」となった人もいるかと。
さて、前置きはここらへんに。(たぶん)わかりやすく、結論を書くとこんな感じです。
- 【WHERE句】集計(GROUP BY)する前にしぼりこみ
- 【HAVING句】集計(GROUP BY)した後にしぼりこみ
- 【WHERE句とHAVING句は併用可】集計する前・した後の両方でフィルターかけるとき
![WHERE句とHAVING句の違い](https://se-piyopiyo.com/wp-content/uploads/2022/05/313ab4c351ff922a91cd71733941ecd8.png)
SQLでデータをとってくるときに、「集計(加工)前のデータか?集計(加工)後のデータか?」が肝心。基本情報技術者試験では、令和元年の秋季試験に出題されています。
WHERE句の使い方【集計する前にしぼりこみ】
WHERE句の使い方は、集計する「前」にしぼりこみをするもの。
エクセルで例えると、フィルター機能。データに対してフィルターをかけてやるイメージです。
■「得点」テーブルがあったとして
![得点テーブル](https://se-piyopiyo.com/wp-content/uploads/2022/05/d5ced5831ceda5b8f8c55b0876866482.png)
■学生番号でフィルターする(下の画像の場合だと、100でフィルター)
![得点テーブルのフィルター](https://se-piyopiyo.com/wp-content/uploads/2022/05/c000f9f3d9377544369aec301bcc0589.png)
「エクセルでフィルターするのがWHERE句」とイメージすれば、フィーリングで読めるかと。
■学生番号でフィルター(WHERE句)
SELECT 学生番号,AVG(点数)
FROM 得点
WHERE 学生番号 = 100
GROUP BY 学生番号
;
HAVING句の使い方【集計した後にしぼりこみ】
HAVING句の使い方は、集計した「後」にしぼりこみをするもの。エクセルで例えると、元のデータからピボットテーブルを作る。集計した後にフィルターをかけてやるイメージ。
※ピボットテーブルがわからん人は、「集計してくれるテーブルがあるんだなぁ」くらいの感じで。
■「得点」テーブルがあったとして
![得点テーブル](https://se-piyopiyo.com/wp-content/uploads/2022/05/d5ced5831ceda5b8f8c55b0876866482.png)
■学生番号で集計して全科目の平均得点をだす
![得点テーブルを学生番号で集計](https://se-piyopiyo.com/wp-content/uploads/2022/05/c56b2738426d9677c8d747a823f34d48.png)
■そのあとに平均得点が80以上の学生番号でしぼりこみ
![学生番号で集計し平均得点が80点以上の生徒](https://se-piyopiyo.com/wp-content/uploads/2022/05/60e547d6face7e46b374e8b6dad80eac.png)
■平均得点でフィルター(HAVING句)
SELECT 学生番号,AVG(点数)
FROM 得点
GROUP BY 学生番号
HAVING 得点 >= 80
;
WHERE句とHAVING句のちがいは、集計する前か後か
WHERE句とHAVING句のちがいは、集計する前か後か。
- 【WHERE句】集計(GROUP BY)する前にしぼりこみ
- 【HAVING句】集計(GROUP BY)した後にしぼりこみ
- 【WHERE句とHAVING句は併用可】集計する前・した後の両方でフィルターかけるとき
WHERE句の誤用(集計後に使用しちゃったパターン)
SELECT 学生番号,AVG(点数)
FROM 得点
GROUP BY 学生番号
WHERE 学生番号 = 100
;
学生番号で集計(GROUP BY)した後に、WHERE句を使用することはできません。
HAVING句の誤用(集計前に使用しちゃったパターン)
SELECT 学生番号,AVG(点数)
FROM 得点
HAVING 得点 >= 80
GROUP BY 学生番号
;
学生番号で集計(GROUP BY)する前に、HAVING句を使用することはできません。
【注意】WHERE句とHAVING句は併用できる
「WHERE句とHAVING句は併用できない」的な文言を、万が一どこかで見かけたら要注意。ふつうに、WHERE句とHAVING句は併用できます。
例えば、「①学生番号103の生徒はカンニングしたから成績から除外して集計。②さらに科目ごとの平均得点が80点以上の科目を知りたい」みたいな場面は、システムエンジニアのお仕事をしていれば、やってきます(´▽`*)。
SELECT 科目,AVG(点数)
FROM 得点
WHERE 学生番号 != 103
GROUP BY 科目
HAVING 得点 >= 80
;
■「得点」テーブルがあったとして
![得点テーブル](https://se-piyopiyo.com/wp-content/uploads/2022/05/d5ced5831ceda5b8f8c55b0876866482.png)
■103の生徒はカンニングしたから除外
![フィルターを集計前と後でする_その1](https://se-piyopiyo.com/wp-content/uploads/2022/05/f1a7202f8f22bf39149d874af62e3aaf.png)
■科目ごとに集計
![フィルターを集計前と後でするその2](https://se-piyopiyo.com/wp-content/uploads/2022/05/6bdfdd861047c65e851719970e63864f.png)
■80点以上の科目をフィルター
![フィルターを集計前と後でするその3](https://se-piyopiyo.com/wp-content/uploads/2022/05/401f9d5eb7da8b45d5d96337e3d17e7a.png)
■集計前後の両方でフィルター
SELECT 科目,AVG(点数)
FROM 得点
WHERE 学生番号 != 103
GROUP BY 科目
HAVING 得点 >= 80
;
WHERE句とHAVING句は、併用できるので覚えておくと便利です。
まとめ
話をまとめると、WHERE句とHAVING句のちがいは、「集計する前か?後か?」です。
- 【WHERE句】集計(GROUP BY)する前にしぼりこみ
- 【HAVING句】集計(GROUP BY)した後にしぼりこみ
- 【WHERE句とHAVING句は併用可】集計する前・した後の両方でフィルターかけるとき
集計前、もっといえば、GROUP BYする前はWHERE句。
集計後、もっといえば、GROUP BYした後はHAVING句。
と覚えておくとよい感じだと思ってくださいまし(-_-;)。
コメント