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

MySQLで複数のSELECT結果を統合する方法:GROUP BY句とHAVINGの活用テクニック

はじめに

MySQLで複数のSELECT条件に一致するレコードをまとめて取得したい場合、GROUP BY句HAVING句を組み合わせることで実現できます。本記事では、具体的なサンプルテーブルを作成しながら、その手順をわかりやすく解説します。

サンプルテーブルの作成

まずは、動作確認用のテーブルを作成しましょう。以下のSQLを実行して、部屋とサービスの関連情報を管理するテーブルを定義します。

mysql> create table MergingSelectDemo
    -> (
    -> RoomServicesId int,
    -> RoomId int,
    -> ServiceId int
    -> );
Query OK, 0 rows affected (1.98 sec)

このテーブルには、次の3つのカラムがあります。

  • RoomServicesId:部屋サービスの一意なID
  • RoomId:部屋を識別するID
  • ServiceId:サービスを識別するID

テストデータの挿入

続いて、INSERT文を使ってサンプルデータを登録します。以下のクエリを実行してください。

mysql> insert into MergingSelectDemo values(10,10,10);
Query OK, 1 row affected (0.29 sec)
mysql> insert into MergingSelectDemo values(20,10,20);
Query OK, 1 row affected (0.22 sec)
mysql> insert into MergingSelectDemo values(30,10,30);
Query OK, 1 row affected (0.14 sec)
mysql> insert into MergingSelectDemo values(50,10,50);
Query OK, 1 row affected (0.19 sec)
mysql> insert into MergingSelectDemo values(110,20,20);
Query OK, 1 row affected (0.14 sec)
mysql> insert into MergingSelectDemo values(120,20,30);
Query OK, 1 row affected (0.37 sec)

登録データの確認

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

mysql> select *from MergingSelectDemo;

実行結果は以下の通りです。

+----------------+--------+-----------+
| RoomServicesId | RoomId | ServiceId |
+----------------+--------+-----------+
|              10 |      10 |         10 |
|              20 |      10 |         20 |
|              30 |      10 |         30 |
|              50 |      10 |         50 |
|             110 |      20 |         20 |
|             120 |      20 |         30 |
+----------------+--------+-----------+
6 rows in set (0.00 sec)

複数のSELECT条件を統合するクエリ

ここからが本題です。たとえば「ServiceIdが10、20、30のすべてを持つ部屋(RoomId)」を抽出したい場合、GROUP BY句でRoomIdごとにグループ化し、HAVING句でカウント数を絞り込みます。

mysql> select RoomId from MergingSelectDemo
    -> where ServiceId IN(10,20,30)
    -> group by RoomId
    -> HAVING COUNT(*)=3;

実行結果は以下の通りです。

+--------+
| RoomId |
+--------+
|     10 |
+--------+
1 row in set (0.15 sec)

クエリの解説

このクエリの仕組みを順番に見ていきましょう。

  1. WHERE ServiceId IN(10,20,30):ServiceIdが10、20、30のいずれかに一致する行だけを対象にします。RoomId=10には4件中3件が該当し、RoomId=20には2件のみ該当します。
  2. GROUP BY RoomId:RoomIdごとに行をグループ化します。
  3. HAVING COUNT(*)=3:グループ内の行数がちょうど3件であるグループだけを残します。つまり、指定した3つのサービスをすべて持つ部屋のみが抽出されます。

その結果、RoomId=10だけが返されました。RoomId=20はServiceId=10を持っていないため、条件を満たさなかったのです。

応用ポイント

この手法は「IN句で指定した値をすべて含むレコードの親キーを検索する」という場面で非常に便利です。条件の数が変わる場合は、IN句の中身とHAVING COUNT(*)の値を揃えるだけで対応できます。また、DISTINCTを併用すれば、同一の組み合わせが重複している場合にも正確に集計できます。

select RoomId from MergingSelectDemo
where ServiceId IN(10,20,30)
group by RoomId
having COUNT(DISTINCT ServiceId)=3;

まとめ

MySQLで複数のSELECT条件を統合的に判定したい場合は、GROUP BY句によるグループ化と、HAVING COUNT(*)による件数フィルタリングを組み合わせるのが基本のアプローチです。データの重複が懸念される場合はCOUNT(DISTINCT カラム名)を使うことで、より堅牢なクエリになります。ぜひ実際の開発でも活用してみてください。

  1. 複数のWord文書を1つに結合する方法|「オブジェクトの挿入」で簡単にマージする手順

    Wordを頻繁に使っている方なら、複数のWord文書を1つのファイルにまとめたい場面に遭遇したことがあるはずです。実はこの操作、Wordなら難しくなく行えますが、その方法はあまり直感的ではありません。 これほど高度な処理ができるソフトなのだから、Microsoftが「文書の結合」機能を標準搭載してくれればいいのにと思うこともありますよね。そこで本記事では、複数のWord文書をすばやく簡単に1つにまとめる方法をご紹介します。 対応バージョンと注意点 まず押さえておきたいのは、この手順がOffice 2007から2016までのほぼすべてのバージョンで使えるという点です。また、筆者の検証では、文書を

  2. MySQLで複数テーブルの結果をマージする方法|JOINを使った結合手順を解説

    MySQLで2つ以上のテーブルに分かれたデータを1つの結果としてまとめたい場合、JOIN(結合)を使うのが最もシンプルで効果的な方法です。この記事では、実際にテーブルを作成しながら、JOINによる結果のマージ手順をわかりやすく解説します。マージに使用するJOINの基本構文結果をマージするには、以下のような構文でシンプルなJOINを使用します。SELECT aliasName1.yourColumnName1, aliasName1.yourColumnName2, ... aliasName2.yourColumnName1 FROM yourTableName1 aliasN