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

MySQLのGROUP BY句で各グループから1行だけを選択・抽出する方法

MySQLでは、GROUP BY句とサブクエリを組み合わせることで、各グループから特定の1行(たとえば最小のIDを持つ行)を取り出すことができます。本記事では、学生の点数データを例に、テーブル作成から実際のクエリ実行までの手順をわかりやすく解説します。

1. テーブルの作成

まず、以下のCREATE TABLE文でサンプル用のテーブルを作成します。

mysql> create table DemoTable1572
    -> (
    -> StudentId int,
    -> StudentMarks int,
    -> StudentName varchar(20)
    -> );
Query OK, 0 rows affected (0.56 sec)

2. レコードの挿入

続いて、INSERT文を使ってサンプルデータを登録します。

mysql> insert into DemoTable1572 values(1,79,'Sam');
Query OK, 1 row affected (0.10 sec)
mysql> insert into DemoTable1572 values(2,89,'Chris');
Query OK, 1 row affected (0.12 sec)
mysql> insert into DemoTable1572 values(3,98,'David');
Query OK, 1 row affected (0.22 sec)
mysql> insert into DemoTable1572 values(4,79,'Bob');
Query OK, 1 row affected (0.10 sec)

3. 登録データの確認

SELECT文ですべてのレコードを表示してみましょう。

mysql> select * from DemoTable1572;

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

+-----------+--------------+-------------+
| StudentId | StudentMarks | StudentName |
+-----------+--------------+-------------+
|         1 |          79 |     Sam   |
|         2 |          89 |     Chris |
|         3 |          98 |     David |
|         4 |          79 |     Bob   |
+-----------+--------------+-------------+
4 rows in set (0.00 sec)

4. GROUP BY句で各グループの先頭行を選択する

ここで注目すべきは、StudentId 1(Sam)と4(Bob)が同じ点数「79」を持っている点です。各点数グループから最小のStudentIdを持つ行だけを取得したい場合は、次のようなクエリを実行します。

mysql> select * from DemoTable1572
    -> where StudentId in (select min(StudentId) from DemoTable1572 group by StudentMarks);

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

+-----------+--------------+-------------+
| StudentId | StudentMarks | StudentName |
+-----------+--------------+-------------+
|         1 |          79 |     Sam   |
|         2 |          89 |     Chris |
|         3 |          98 |     David |
+-----------+--------------+-------------+
3 rows in set (0.10 sec)

クエリの仕組み

このクエリが期待どおりに動作する理由は以下の通りです。

  • サブクエリ (select min(StudentId) from DemoTable1572 group by StudentMarks) が、点数(StudentMarks)ごとに行をグループ化し、各グループ内で最小のStudentIdを返します。
  • 外側のクエリは WHERE ... IN を使って、そのIDリストに一致する行だけを抽出します。
  • その結果、同じ点数を持つ行が複数存在しても、各グループの先頭(最小ID)の行のみが表示されます。上記の例では、点数79のBob(ID: 4)が除外され、Sam(ID: 1)だけが残ります。

この手法は、「重複するカテゴリの中から最初の1件だけを取得したい」というケースで非常に便利です。なお、最大値を取得したい場合は min()max() に置き換えるだけで同様の動作になります。

  1. 単一のMySQLクエリでGROUP BYとFIELD関数を組み合わせて任意の順序で並べ替える方法

    MySQLでは、GROUP BY句とORDER BY FIELD()関数を組み合わせることで、グループ化した結果を指定したカスタム順序で並べ替えることができます。この記事では、実際にテーブルを作成し、データを挿入しながら、その手順をわかりやすく解説します。1. サンプルテーブルの作成まず、テスト用のテーブルを作成します。ここでは、メッセージ文字列を格納する「DemoTable」というテーブルを用意します。mysql> create table DemoTable ( Message text ); Query OK, 0 rows affected (1.15 sec)2. レコ

  2. MySQLのORDER BY CASEとIN()を使ってグループ化したフィールドを並べ替える方法

    MySQLでグループ化したフィールドを並べ替えるには?グループ化されたフィールドに対して並べ替えを行いたい場合は、ORDER BY CASEとIN()を組み合わせて使用します。CASE式は複数の条件を評価して優先順位を決め、ORDER BYはその結果をもとに値を昇順または降順にソートします。また、MySQLのIN()は指定した複数の値の中から一致するものを検索するために使われます。この仕組みにより、「特定の値をまとめて先頭に表示したい」「カスタム順序でソートしたい」といった柔軟な並べ替えが可能になります。1. テーブルを作成するまず、サンプル用のテーブルを作成しましょう。mysql> c