CodeGym /コース /SQL SELF /WHEREとHAVINGの比較:実行順序の解説とサンプル

WHEREとHAVINGの比較:実行順序の解説とサンプル

SQL SELF
レベル 8 , レッスン 2
使用可能

もう一度、SQLでの処理の順番と、WHEREとHAVINGが何に使えて何に使えないかを見ていこう。これ、めっちゃ大事なポイントで、SQLクエリの細かい動きの理解に直結するから、しっかり押さえておこう!

じゃあ、WHEREHAVINGって何が違うの?どっちをいつ使う?どう関係してる?この辺を整理しておくと、クエリのロジックで迷わなくなるし、データのフィルタも効率的にできるよ。WHEREHAVINGについて、知識をまとめてみよう!

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
使うタイミング グループ化前に行をフィルタ グループ化後にグループをフィルタ
集計との関係 集計関数は使えない 集計関数が使える
目的 グループ化のために余計な行を除外 条件に合わないグループを除外

WHEREGROUP BYHAVINGの実行順序

WHEREHAVINGの動きをもっと理解するために、SQLクエリの実行順序を見てみよう:

  1. まずFROMでテーブルから行を選ぶ。
  2. 次にWHEREで条件に合う行だけフィルタ。
  3. その後GROUP BYでグループ化。新しいグループごとのテーブルができる。
  4. HAVINGで条件に合うグループだけ残す。
  5. 最後に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;

このクエリの流れ:

  1. studentsテーブルからage > 18の行を選ぶ(WHERE)。
  2. 残った行をdepartmentでグループ化。
  3. 各グループの平均年齢を計算。
  4. 平均年齢が20以下のグループをHAVINGで除外。
  5. 結果を出力。

組み合わせた使い方の例

例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

解説:

  1. まずage <= 18の行を除外(WHEREの条件)。
  2. 学部ごとにグループ化(GROUP BY department)。
  3. 各グループの学生数を計算。
  4. 学生が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;

複雑な条件にはWHEREHAVINGを組み合わせて使おう。

例:人口が100万を超える都市だけを対象に、合計人口が1000万を超える国を探す。

SELECT country, SUM(population) AS total_population
FROM cities
WHERE population > 1000000
GROUP BY country
HAVING SUM(population) > 10000000;

よくあるミスとその対策

一番ありがちなミスは、WHEREHAVINGの混同。例えば、集計関数を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;

これでWHEREHAVINGの違い、正しい使い方、よくあるミスの回避法がバッチリ分かったはず!この知識は、複雑なレポート作成やデータ分析、クエリの最適化でめっちゃ役立つよ。つまり、実際に書くSQLクエリの半分以上で使うことになるからね :)

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION