MySQLでGROUP BYとHAVING句を使って2つの異なる値を持つレコードをすべて取得する方法
MySQLである列(この例では学生名)ごとに、別の列(科目名)に2つ以上の異なる値が登録されているレコードをすべて取得したいケースはよくあります。たとえば、「MySQL」と「MongoDB」の両方を受講している学生だけを抽出したい場合などです。
このような条件でのデータ抽出には、GROUP BY句とHAVING句を組み合わせて使用します。以下、テーブル作成からクエリ実行までの手順をサンプルコードとともに解説します。
1. サンプルテーブルの作成
まず、学生名と科目名を格納するテーブルを作成します。
mysql> create table DemoTable751 ( StudentName varchar(100), SubjectName varchar(100) ); Query OK, 0 rows affected (0.66 sec)
2. レコードの挿入
次に、INSERT文を使ってサンプルデータを登録していきます。
mysql> insert into DemoTable751 values('John','MySQL');
Query OK, 1 row affected (0.14 sec)
mysql> insert into DemoTable751 values('John','MongoDB');
Query OK, 1 row affected (0.14 sec)
mysql> insert into DemoTable751 values('Sam','MySQL');
Query OK, 1 row affected (0.17 sec)
mysql> insert into DemoTable751 values('Carol','Java');
Query OK, 1 row affected (0.21 sec)
mysql> insert into DemoTable751 values('David','MySQL');
Query OK, 1 row affected (0.16 sec)
mysql> insert into DemoTable751 values('Carol','MongoDB');
Query OK, 1 row affected (0.17 sec)
3. 登録されたデータの確認
SELECT文ですべてのレコードを表示してみましょう。
mysql> select *from DemoTable751;
実行結果は以下のとおりです。
+-------------+-------------+ | StudentName | SubjectName | +-------------+-------------+ | John | MySQL | | John | MongoDB | | Sam | MySQL | | Carol | Java | | David | MySQL | | Carol | MongoDB | +-------------+-------------+ 6 rows in set (0.00 sec)
4. 複数の異なる値を持つレコードを取得するクエリ
ここからが本題です。GROUP BY句で学生名ごとにグループ化し、HAVING句で「科目数が2以上」のグループだけを絞り込みます。
mysql> select StudentName from DemoTable751 group by StudentName having count(SubjectName) > 1;
実行結果は以下のとおりです。
+-------------+ | StudentName | +-------------+ | John | | Carol | +-------------+ 2 rows in set (0.00 sec)
この結果、「John」と「Carol」はそれぞれ2つの異なる科目を受講しているため抽出されました。「Sam」と「David」は1科目しか受講していないため、結果から除外されています。
クエリのポイント解説
- GROUP BY StudentName:学生名ごとにレコードをグループ化します。
- HAVING count(SubjectName) > 1:グループ化後の各グループに対して条件を適用し、科目が2件以上あるグループのみを抽出します。WHERE句は集計前の行に対する条件しか指定できないため、集計結果で絞り込むにはHAVING句を使うのがポイントです。
より厳密に「異なる値」を判定したい場合
なお、上記のクエリは単純に行数をカウントしているため、同じ科目が重複して登録されているデータがあると正しく判定できません。「値の種類」そのものを数えたい場合は、COUNT(DISTINCT ...) を使用すると安全です。
mysql> select StudentName from DemoTable751 group by StudentName having count(distinct SubjectName) > 1;
このようにGROUP BY句とHAVING句を組み合わせることで、特定の列に複数の異なる値を持つレコードを簡単かつ効率的に抽出できます。ログ分析や受講履歴の集計など、さまざまな場面で応用できるテクニックなので、ぜひ覚えておきましょう。
-
MySQLで重複する値ごとのレコードを別の列に合計して表示する方法
MySQLでは、重複している値(同じ名前など)を持つ複数のレコードの数値を、名前ごとにまとめて合計したいケースがあります。このような場合には、集計関数SUM()とGROUP BY句を組み合わせることで簡単に実現できます。本記事では、実際にサンプルテーブルを作成し、重複する値を持つレコードを別の列(合計列)として集計・表示する手順を解説します。1. サンプルテーブルを作成するまず、CREATE TABLE文を使ってテーブルを作成します。mysql> create table DemoTable -> ( -> Name varchar(20), -> V
-
MySQLで条件に応じて同じ列の2つの値を連結する方法
MySQLで条件に応じて同じ列の2つの値を連結する方法 MySQLでは、max() などの集計関数と CASE 式を組み合わせることで、条件の異なる同じ列の値を1つの文字列として連結できます。この記事では、サンプルテーブルを作成しながら、具体的な手順をわかりやすく解説します。 1. サンプルテーブルの作成 まず、create table コマンドでテーブルを作成しましょう。 mysql> create table DemoTable1869 ( Id int, &nb