【MySQL】SELECT文で重複・類似行を除外し、最大値を持つ行を取得する方法
はじめに
データベースを運用していると、内容が重複したレコードが登録されてしまうことがあります。こうしたケースでは、GROUP BY句とHAVING句を組み合わせることで、重複行をまとめつつ、各グループ内で最大値を持つ行だけを効率的に抽出できます。
本記事では、MySQLで重複・類似コンテンツの行を除外し、SELECT文で最大値を持つ行を取得する手順を、具体的なサンプルコード付きで解説します。
1. サンプルテーブルの作成
まず、以下のCREATE TABLE文でテーブルを作成します。
mysql> create table DemoTable1468
-> (
-> Id int,
-> Name varchar(20),
-> Age int
-> );
Query OK, 0 rows affected (1.21 sec)
2. テストデータの挿入
次に、INSERTコマンドでレコードを挿入します。ここでは、IdとNameが重複するデータを意図的に含めています。
mysql> insert into DemoTable1468 values(100,'Chris',23);
Query OK, 1 row affected (0.19 sec)
mysql> insert into DemoTable1468 values(101,'Bob',25);
Query OK, 1 row affected (0.12 sec)
mysql> insert into DemoTable1468 values(102,'David',30);
Query OK, 1 row affected (0.11 sec)
mysql> insert into DemoTable1468 values(100,'Chris',23);
Query OK, 1 row affected (0.35 sec)
mysql> insert into DemoTable1468 values(100,'Chris',38);
Query OK, 1 row affected (0.14 sec)
mysql> insert into DemoTable1468 values(101,'Bob',23);
Query OK, 1 row affected (0.13 sec)
3. 登録されたレコードの確認
SELECT文ですべてのレコードを表示してみましょう。
mysql> select * from DemoTable1468;
実行結果は以下の通りです。
+------+-------+------+
| Id | Name | Age |
+------+-------+------+
| 100 | Chris | 23 |
| 101 | Bob | 25 |
| 102 | David | 30 |
| 100 | Chris | 23 |
| 100 | Chris | 38 |
| 101 | Bob | 23 |
+------+-------+------+
6 rows in set (0.00 sec)
このように、「Chris」と「Bob」にはId・Nameが重複したレコードが複数存在しています。
4. 重複行を排除し、最大値の行を取得するクエリ
それが本題です。GROUP BY句でNameとIdごとにグループ化し、HAVING句でmax(Age)を指定することで、重複行を取り除きながら年齢の最大値を取得できます。
mysql> select Id,Name,Age from DemoTable1468
-> group by Name,Id
-> having max(Age);
実行結果は以下の通りです。
+------+-------+------+
| Id | Name | Age |
+------+-------+------+
| 100 | Chris | 23 |
| 101 | Bob | 25 |
| 102 | David | 30 |
+------+-------+------+
3 rows in set (0.00 sec)
6件あったレコードが3件に整理され、重複が排除されました。
補足:より確実に最大値を取得するには
上記のクエリではHAVING句にmax(Age)を指定していますが、SQLモード(ONLY_FULL_GROUP_BY)の設定によっては、SELECT句で取得されるAgeが必ずしも最大値になるとは限りません。より確実な方法として、SELECT句でMAX関数を明示的に使うことをおすすめします。
mysql> select Id,Name,max(Age) as MaxAge from DemoTable1468
-> group by Name,Id;
まとめ
- GROUP BY句で重複の基準となるカラム(ここではNameとId)を指定する
- HAVING句やMAX関数を組み合わせることで、各グループの最大値を取得できる
- ONLY_FULL_GROUP_BYモードが有効な環境では、非集計カラムの扱いに注意が必要
GROUP BYと集計関数を活用すれば、重複データの整理と必要な情報の抽出を1つのクエリで簡潔に行えます。ぜひ実務でも活用してみてください。
-
【MySQL】GROUP BYとMAX()を使って同名の学生レコードから最大年齢を取得する方法
はじめに MySQLで、同じ名前の学生が複数登録されているテーブルから、名前ごとの最大年齢を取得したいケースはよくあります。このような場合には、GROUP BY句と集計関数のMAX()を組み合わせることで、シンプルかつ効率的に実現できます。 本記事では、実際にテーブルを作成し、サンプルデータを挿入しながら、学生名ごとに最大年齢を取得する手順を詳しく解説します。 テーブルの作成 まず、サンプル用のテーブルを作成しましょう。 mysql> create table DemoTable1964 ( StudentName varchar(20), StudentAge int
-
MySQLで重複行を除外して1行だけ取得する方法(DISTINCTの使い方)
MySQLで重複行から1行のみを返すには?MySQLのテーブルに同じ値を持つ重複行が存在する場合、DISTINCTキーワードを使うことで、重複を排除した一意な行だけを取得できます。この記事では、実際にテーブルを作成し、データを挿入したうえで、DISTINCTによる重複除去の手順を解説します。1. テーブルを作成するまず、サンプル用のテーブルを作成します。mysql> create table DemoTable1998 ( Name varchar(20) ); Query OK, 0 rows affected (0.61 sec)2. レコードを挿入するINSERTコマンドを