本記事では、海外のSQL学習サイト【SQL Bolt】を利用して、データベース初心者向けにSQLの基本を解説します。
第9回は「SQL Lesson 11: Queries with aggregates (Pt. 2)」のパート2です。
- 「GROUP BY ~ HAVING …」でグループ化された行に対して抽出条件を指定できる
- GROUP BYを使わない場合、WHEREとHAVINGは同じ意味で使える
- GROUP BYを使う場合、WHEREとHAVINGは実行順序が異なる

ざっくり日本語訳
今回のLesson11は、WHERE句の後にGROUP BY句を実行する場合について解説します。

紹介するSQL文もだんだん複雑になってきましたね
「GROUP BY ~ HAVING …」で集計関数を実行する方法
突然「WHERE句の後にGROUP BY句を実行する」と言いましたが、この場合、グループ化された行をどうやってフィルタリングすればよいのでしょうか?
SQLでは、GROUP BY句に続けてHAVING句を追加することで、グループ化された行に対して「集計関数を利用した抽出条件を指定」することができます。
記述方法
SELECT 列名1, 列名2, … 集約関数 AS 集約結果につける別名,
FROM テーブル名
WHERE 条件
GROUP BY 列名 HAVING グループ化の条件;
HAVING句に続く条件部分は、WHERE句の条件と同じ方法で記述してください。
HAVINGとWHEREの違い


SQL Bolt原文のこの部分、「GROUP BY句を使用しないなら、単純なWHERE句で十分」とありますが、筆者なりに少し補足します。



実際のSQL文と実行結果をお見せしながら解説します
GROUP BYを使わない場合:同じ意味
実は、このEmployeeテーブルに対して下の2つのSQL文を実行すると同じ結果になります。


SELECT * from Employees WHERE Role = 'Engineer';
SELECT * from Employees HAVING Role = 'Engineer';




GROUP BYを使う場合:実行順序が異なる
クエリにGROUP BY句が含まれる場合は、WHERE句とHAVING句は使い分けが必要です。
違いは抽出処理を実行する順番。
まず、WHERE句は「クエリが呼び出されてから最初に抽出する行」を絞り込みます。
それに対してHAVING句は、以下の順序で実行されます。
- WHERE句で抽出する行を絞る
- GROUP BY句でグループ化を行う
- 集計関数でデータの集計を行う
- HAVING句で(集計結果を利用して)抽出する行を絞る
演習問題の和訳・解答
- 1. Find the number of Artists in the studio (without a HAVING clause)
-
【和訳】スタジオにいるアーティストの人数を調べてください(HAVING句を使わずに)。
SELECT COUNT(*) FROM employees WHERE Role = "Artist";
- 2. Find the number of Employees of each role in the studio
-
【和訳】スタジオにいる各役割の従業員の数を調べてください。
SELECT Role, COUNT(*) FROM employees GROUP BY Role;
- 3. Find the total number of years employed by all Engineers
-
【和訳】すべてのエンジニアの合計雇用年数を求めてください。
SELECT SUM(Years_employed) FROM employees GROUP BY Role HAVING Role = "Engineer";
コメント