もう一度、SQLでの処理の順番と、WHEREとHAVINGが何に使えて何に使えないかを見ていこう。これ、めっちゃ大事なポイントで、SQLクエリの細かい動きの理解に直結するから、しっかり押さえておこう!
じゃあ、WHEREとHAVINGって何が違うの?どっちをいつ使う?どう関係してる?この辺を整理しておくと、クエリのロジックで迷わなくなるし、データのフィルタも効率的にできるよ。WHEREとHAVINGについて、知識をまとめてみよう!
WHEREって何?
WHEREは、グループ化や集計関数を使う前に行をフィルタするための条件だよ。つまり、まずテーブルから条件に合う行だけを選んで、その後でグループ化とかをやる感じ。
👉 市場でフルーツを集めてるイメージしてみて。WHEREは、サイズや色で分ける前に、傷んだリンゴを先に除外するフィルターみたいなもん。
例:
SELECT *
FROM students
WHERE age > 18;
このクエリは、18歳より上の学生だけを他の処理の前に選ぶよ。
HAVINGって何?
HAVINGは、データをGROUP BYでグループ化した後に使うフィルターだよ。グループ化したデータに条件をつけて、例えば「学生の平均点が80より高いグループだけ残す」みたいなことができる。
👉 またリンゴの例で言うと、HAVINGはカゴ(グループ)ごとに分けた後、「10個以上リンゴが入ってるカゴだけ欲しい」みたいな感じ。
例:
SELECT カゴ, COUNT(*)
FROM リンゴ
GROUP BY カゴ
HAVING COUNT(*) > 10;
このクエリは、リンゴが10個より多いカゴだけを選ぶよ。
主な違い:
| 特徴 | WHERE |
HAVING |
|---|---|---|
| 使うタイミング | グループ化前に行をフィルタ | グループ化後にグループをフィルタ |
| 集計との関係 | 集計関数は使えない | 集計関数が使える |
| 目的 | グループ化のために余計な行を除外 | 条件に合わないグループを除外 |
WHERE、GROUP BY、HAVINGの実行順序
WHEREとHAVINGの動きをもっと理解するために、SQLクエリの実行順序を見てみよう:
- まず
FROMでテーブルから行を選ぶ。 - 次に
WHEREで条件に合う行だけフィルタ。 - その後
GROUP BYでグループ化。新しいグループごとのテーブルができる。 HAVINGで条件に合うグループだけ残す。- 最後に
SELECTで結果を選ぶ。
ざっくり図にすると:
1. FROM → 2. WHERE → 3. GROUP BY → 4. HAVING → 5. SELECT
例:
SELECT department, AVG(age) AS avg_age
FROM students
WHERE age > 18
GROUP BY department
HAVING AVG(age) > 20;
このクエリの流れ:
studentsテーブルからage > 18の行を選ぶ(WHERE)。- 残った行を
departmentでグループ化。 - 各グループの平均年齢を計算。
- 平均年齢が20以下のグループを
HAVINGで除外。 - 結果を出力。
組み合わせた使い方の例
例1:グループ化前後でのフィルタ
条件:18歳より上の学生だけを対象に、学生が5人より多い学部を探す。
元のテーブルstudents
| id | name | department | age | gpa |
|---|---|---|---|---|
| 1 | Alex Lin | ComputerSci | 20 | 3.8 |
| 2 | Maria Chi | Math | 22 | 3.5 |
| 3 | Anna Song | ComputerSci | 19 | 4.0 |
| 4 | Otto Art | Math | 17 | 3.9 |
| 5 | Liam Park | Physics | 21 | 3.7 |
| 6 | Jane Doe | ComputerSci | 23 | 3.6 |
| 7 | Tom Brown | Math | 25 | 3.4 |
| 8 | Sara White | Math | 19 | 3.8 |
| 9 | John Smith | ComputerSci | 20 | 3.7 |
| 10 | Emily Green | Physics | 18 | 3.9 |
| 11 | Mark Blue | ComputerSci | 21 | 3.5 |
| 12 | Zoe Black | Math | 22 | 3.6 |
| 13 | Max Gray | ComputerSci | 20 | 3.9 |
| 14 | Eva Gold | Math | 23 | 3.7 |
| 15 | Nick Silver | Physics | 19 | 3.8 |
クエリ:
SELECT department, COUNT(*) AS student_count
FROM students
WHERE age > 18
GROUP BY department
HAVING COUNT(*) > 5;
結果: -- クエリの結果
| department | student_count |
|---|---|
| ComputerSci | 6 |
解説:
- まず
age <= 18の行を除外(WHEREの条件)。 - 学部ごとにグループ化(
GROUP BY department)。 - 各グループの学生数を計算。
- 学生が5人以下のグループを除外(
HAVING COUNT(*) > 5)。
例2:WHEREの代わりにHAVINGを使うべきケースのミス
条件:平均年齢が22歳より高い学部を探す。
間違ったクエリ:
SELECT department, AVG(age) AS avg_age
FROM students
WHERE AVG(age) > 22
GROUP BY department;
エラー:この段階ではAVGなどの集計関数はWHEREで使えない。まだ集計が終わってないからね。
正しいクエリ:
SELECT department, AVG(age) AS avg_age
FROM students
GROUP BY department
HAVING AVG(age) > 22;
ここではAVG(age) > 22の条件はグループ化の後に適用される。
実践アドバイス
行をフィルタしたいならWHEREを使おう。例:給料が5000より多い従業員を探す。
SELECT *
FROM employees
WHERE salary > 5000;
グループをフィルタしたいならHAVINGを使おう。例:合計給料が100,000より多い部署を探す。
SELECT department, SUM(salary) AS total_salary
FROM employees
GROUP BY department
HAVING SUM(salary) > 100000;
複雑な条件にはWHEREとHAVINGを組み合わせて使おう。
例:人口が100万を超える都市だけを対象に、合計人口が1000万を超える国を探す。
SELECT country, SUM(population) AS total_population
FROM cities
WHERE population > 1000000
GROUP BY country
HAVING SUM(population) > 10000000;
よくあるミスとその対策
一番ありがちなミスは、WHEREとHAVINGの混同。例えば、集計関数をWHEREで使おうとすること:
SELECT department, COUNT(*)
FROM students
WHERE COUNT(*) > 10
GROUP BY department;
このクエリはエラーになる。集計はWHEREの段階ではまだできないから。正しいやり方はHAVINGを使うこと:
SELECT department, COUNT(*)
FROM students
GROUP BY department
HAVING COUNT(*) > 10;
もう一つのミスは、WHEREで間違った条件を使うこと。例えば:
SELECT department, AVG(age) AS avg_age
FROM students
WHERE avg_age > 20
GROUP BY department;
ここでavg_age > 20はダメ。avg_ageはまだ計算されてないから。解決策はこの条件をHAVINGに移すこと:
SELECT department, AVG(age) AS avg_age
FROM students
GROUP BY department
HAVING AVG(age) > 20;
これでWHEREとHAVINGの違い、正しい使い方、よくあるミスの回避法がバッチリ分かったはず!この知識は、複雑なレポート作成やデータ分析、クエリの最適化でめっちゃ役立つよ。つまり、実際に書くSQLクエリの半分以上で使うことになるからね :)
GO TO FULL VERSION