MySQLで1つまたは複数の列に基づいて重複行をすべて選択する方法
MySQLで特定の列に基づく重複行をすべて抽出したい場合、サブクエリとHAVING句を組み合わせることで実現できます。この記事では、実際にテーブルを作成し、データを挿入しながら、重複行を検出するクエリの書き方を具体的に解説します。
サンプルテーブルの作成
まず、CREATE TABLE文を使ってデモ用のテーブルを作成しましょう。
mysql> create table DemoTable
(
StudentId int NOT NULL AUTO_INCREMENT PRIMARY KEY,
StudentFirstName varchar(20),
StudentLastName varchar(20)
);
Query OK, 0 rows affected (0.27 sec)
このテーブルは、学生ID(StudentId)を主キーとし、名(StudentFirstName)と姓(StudentLastName)を持つシンプルな構造です。
テストデータの挿入
次に、INSERTコマンドを使用していくつかのレコードを登録します。意図的に「John」という同じ名(StudentFirstName)を持つ複数のレコードを含めています。
mysql> insert into DemoTable(StudentFirstName,StudentLastName) values('John','Smith');
Query OK, 1 row affected (0.04 sec)
mysql> insert into DemoTable(StudentFirstName,StudentLastName) values('Carol','Taylor');
Query OK, 1 row affected (0.04 sec)
mysql> insert into DemoTable(StudentFirstName,StudentLastName) values('John','Doe');
Query OK, 1 row affected (0.17 sec)
mysql> insert into DemoTable(StudentFirstName,StudentLastName) values('John','Brown');
Query OK, 1 row affected (0.05 sec)
mysql> insert into DemoTable(StudentFirstName,StudentLastName) values('David','Miller');
Query OK, 1 row affected (0.06 sec)
登録済みレコードの確認
SELECT文ですべてのレコードを表示して、データが正しく登録されているか確認しましょう。
mysql> select *from DemoTable;
実行すると、以下のような結果が出力されます。
+-----------+------------------+-----------------+ | StudentId | StudentFirstName | StudentLastName | +-----------+------------------+-----------------+ | 1 | John | Smith | | 2 | Carol | Taylor | | 3 | John | Doe | | 4 | John | Brown | | 5 | David | Miller | +-----------+------------------+-----------------+ 5 rows in set (0.00 sec)
ご覧のとおり、「John」という名前が3件(StudentId: 1、3、4)存在しています。
重複行を抽出するクエリ
それでは本題です。1つまたは2つの列に基づいて重複行をすべて選択するには、以下のようにサブクエリとHAVING句を組み合わせます。ここでは、名(StudentFirstName)が2回以上出現している、つまり重複しているレコードをカウントして抽出しています。
mysql> select StudentId from DemoTable where StudentFirstName=(select StudentFirstName from DemoTable having count(StudentFirstName) > 1);
このクエリを実行すると、以下の結果が得られます。
+-----------+ | StudentId | +-----------+ | 1 | | 3 | | 4 | +-----------+ 3 rows in set (0.03 sec)
結果として、名が「John」で重複している3件のレコード(StudentId: 1、3、4)だけが抽出されました。
補足:GROUP BYを使ったより汎用的な方法
上記の方法は単一の値に対するチェックに適していますが、より汎用的に重複を検出したい場合は、GROUP BY句とHAVING句を組み合わせる方法も便利です。
mysql> SELECT * FROM DemoTable
WHERE StudentFirstName IN (
SELECT StudentFirstName FROM DemoTable
GROUP BY StudentFirstName
HAVING COUNT(*) > 1
);
この書き方なら、どの値が重複しているかを自動的に判定できるため、実務のデータクリーニングや整合性チェックの場面で幅広く活用できます。姓と名の両方(2列)を基準に重複を判定したい場合は、GROUP BYに両方の列を指定すればOKです。
-
MySQLで列を行に変換して結合する方法:UNION ALLの使い方
MySQLで複数の列のデータを1つの列に縦方向(行)へ結合したい場合は、UNION ALLを使用します。UNION ALLは複数のSELECT文の結果をそのまま連結する演算子のため、重複を排除することなくすべての行を取得できるのが特徴です。基本構文select yourColumnName1 from yourTableName union allselect yourColumnName2 from yourTableName;それでは、実際にサンプルテーブルを作成し、動作を確認していきましょう。テーブルの作成mysql> create table DemoTable -&
-
MySQLで2列の合計値が最大となるレコードを取得する方法
MySQLで2列の合計値が最大となるレコードを取得する方法 2列の合計値の最大値を取得するには、集計関数MAX()とサブクエリを組み合わせて使用します。まずはサンプル用のテーブルを作成しましょう。 mysql> create table DemoTable1587 -> ( -> Value1 int, -> Value2 int -> ); Query OK, 0 rows affected (0.59 sec) 続いて、insertコマンドを使ってテーブルにいくつかのレコードを挿入します。 mysql> insert in