MySQL
 Computer >> コンピューター >  >> プログラミング >> MySQL

MySQLのGROUP BYとHAVING句を使った条件絞り込みの方法

MySQLでは、GROUP BYでグループ化した結果に対して条件を指定したい場合、WHEREではなくHAVING句を使用します。本記事では、GROUP BYとHAVINGを組み合わせて、最大値(MAX)に基づく条件でデータを抽出する方法を、具体的なサンプルコードとともに解説します。

HAVING句とGROUP BYの基本構文

GROUP BYの結果に対してHAVINGで条件を設定する際の基本構文は以下の通りです。ここでは、MAX関数を使って「グループ内の最大値が指定した値より小さい」という条件を設定しています。

SELECT yourColumnName FROM yourTableName 
GROUP BY yourColumnName 
HAVING MAX(yourColumnName) < yourValue;

サンプルテーブルの作成

それでは、実際にMySQLでテーブルを作成して動作を確認してみましょう。まずはユーザーID、プロセスID、スレッドIDを持つテーブルを作成します。

mysql> create table WhereAfterGroupDemo
-> (
-> UserId int NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> UserProcess int,
-> UserThreadId int
-> );
Query OK, 0 rows affected (5.74 sec)

テストデータの挿入

次に、INSERT文を使ってテーブルにレコードを挿入します。

mysql> insert into WhereAfterGroupDemo(UserProcess,UserThreadId) values(1211,3);
Query OK, 1 row affected (0.10 sec)
mysql> insert into WhereAfterGroupDemo(UserProcess,UserThreadId) values(1412,3);
Query OK, 1 row affected (0.39 sec)
mysql> insert into WhereAfterGroupDemo(UserProcess,UserThreadId) values(1510,4);
Query OK, 1 row affected (0.19 sec)
mysql> insert into WhereAfterGroupDemo(UserProcess,UserThreadId) values(1511,4);
Query OK, 1 row affected (0.31 sec)

登録データの確認

SELECT文ですべてのレコードを表示して、データが正しく登録されているか確認します。

mysql> select *from WhereAfterGroupDemo;

実行結果

+--------+-------------+--------------+
| UserId | UserProcess | UserThreadId |
+--------+-------------+--------------+
|      1 | 1211        |            3 |
|      2 | 1412        |            3 |
|      3 | 1510        |            4 |
|      4 | 1511        |            4 |
+--------+-------------+--------------+
4 rows in set (0.00 sec)

この結果から、スレッドID「3」にはプロセス値1211と1412が、スレッドID「4」には1510と1511が登録されていることがわかります。

HAVING句で最大値条件を指定したクエリ

それでは本題のクエリです。UserThreadIdでグループ化し、そのグループ内のUserProcessの最大値が1510未満であるスレッドIDを取得します。

mysql> SELECT UserThreadId FROM WhereAfterGroupDemo 
GROUP BY UserThreadId 
HAVING MAX(UserProcess) < 1510;

実行結果

+--------------+
| UserThreadId |
+--------------+
|            3 |
+--------------+
1 row in set (0.00 sec)

結果の解説

実行結果として返されたのはスレッドID「3」のみでした。これは以下の理由によるものです。

  • スレッドID 3: グループ内の最大値は1412であり、1510未満のため条件を満たす
  • スレッドID 4: グループ内の最大値は1511であり、1510以上のため条件から除外される

WHERE句との違いに注意

GROUP BYと組み合わせる際、集計後の結果に条件を適用する場合は必ずHAVING句を使う必要があります。WHERE句はグループ化の個々の行に対してフィルタリングを行うため、MAXやSUMなどの集計関数の結果に対する条件は記述できません。この点を理解しておくことで、意図した通りのデータ抽出が可能になります。

  1. MySQLでGROUP BYのように特定の1行だけ更新する方法|ORDER BYとLIMITを活用したUPDATE文の書き方

    MySQLでは、UPDATE文の中でGROUP BYを直接使用することができません。しかし、「同じ値を持つ複数のレコードの中から、最初の1行だけを更新したい」というケースは実際の開発でよく発生します。 そんなときに役立つのが、ORDER BYとLIMITを組み合わせたUPDATE文です。この記事では、サンプルテーブルを使いながら、その具体的な手順をわかりやすく解説します。 1. サンプルテーブルを作成する まず、従業員情報を格納するテーブル「DemoTable2018」を作成します。テーブルには、自動採番される主キー「EmployeeId」、従業員名「EmployeeName」、給与「Emp

  2. ApacheとMySQLを連携させる方法|ユーザー認証とログ管理の基本

    ApacheとMySQLの連携とは本記事では、Webサーバー「Apache」とデータベース「MySQL」を組み合わせて活用する方法を解説します。Apacheは、Apache Software Foundationによって開発・保守されているWebサーバーソフトウェアです。ユーザーからWebページへのアクセス要求(リクエスト)を受け付け、いくつかのセキュリティチェックを実施したうえで、目的のページへとユーザーを誘導します。MySQLによるユーザー認証MySQLデータベースを使ってユーザー認証を行えるプログラムは数多く存在します。これらのプログラムを利用すれば、アクセスログをMySQLのテーブルに