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

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句を組み合わせることで、特定の列に複数の異なる値を持つレコードを簡単かつ効率的に抽出できます。ログ分析や受講履歴の集計など、さまざまな場面で応用できるテクニックなので、ぜひ覚えておきましょう。

  1. MySQLで重複する値ごとのレコードを別の列に合計して表示する方法

    MySQLでは、重複している値(同じ名前など)を持つ複数のレコードの数値を、名前ごとにまとめて合計したいケースがあります。このような場合には、集計関数SUM()とGROUP BY句を組み合わせることで簡単に実現できます。本記事では、実際にサンプルテーブルを作成し、重複する値を持つレコードを別の列(合計列)として集計・表示する手順を解説します。1. サンプルテーブルを作成するまず、CREATE TABLE文を使ってテーブルを作成します。mysql> create table DemoTable -> ( -> Name varchar(20), -> V

  2. MySQLで条件に応じて同じ列の2つの値を連結する方法

    MySQLで条件に応じて同じ列の2つの値を連結する方法 MySQLでは、max() などの集計関数と CASE 式を組み合わせることで、条件の異なる同じ列の値を1つの文字列として連結できます。この記事では、サンプルテーブルを作成しながら、具体的な手順をわかりやすく解説します。 1. サンプルテーブルの作成 まず、create table コマンドでテーブルを作成しましょう。 mysql> create table DemoTable1869     (     Id int,   &nb