MySQLで重複している値(複数回出現するデータ)を抽出する方法
テーブル内に2回以上出現する値(重複データ)を抽出したい場合、「GROUP BY」句と「HAVING」句を「COUNT(*)」関数と組み合わせて使用します。WHERE句は集計前の行に対して条件を適用するため、集計後の結果を絞り込むにはHAVING句が必要になる点がポイントです。
1. サンプルテーブルを作成する
まず、検証用のテーブルを作成しましょう。
mysql> create table DemoTable -> ( -> Value int -> ); Query OK, 0 rows affected (0.47 sec)
2. テストデータを挿入する
INSERT文を使って、いくつかのレコードを登録します。
mysql> insert into DemoTable values(20); Query OK, 1 row affected (0.18 sec) mysql> insert into DemoTable values(10); Query OK, 1 row affected (0.08 sec) mysql> insert into DemoTable values(30); Query OK, 1 row affected (0.12 sec) mysql> insert into DemoTable values(10); Query OK, 1 row affected (0.16 sec) mysql> insert into DemoTable values(30); Query OK, 1 row affected (0.12 sec) mysql> insert into DemoTable values(40); Query OK, 1 row affected (0.12 sec) mysql> insert into DemoTable values(50); Query OK, 1 row affected (0.27 sec)
3. 登録したデータを確認する
SELECT文ですべてのレコードを表示します。
mysql> select *from DemoTable;
実行すると、次のような結果が得られます。
+-------+ | Value | +-------+ | 20 | | 10 | | 30 | | 10 | | 30 | | 40 | | 50 | +-------+ 7 rows in set (0.00 sec)
4. 重複している値を抽出するクエリ
ここからが本題です。2回以上出現する値だけを取り出すには、以下のようにクエリを記述します。
mysql> select *from DemoTable -> group by Value -> having count(*) > 1;
実行結果は次のとおりです。
+-------+ | Value | +-------+ | 10 | | 30 | +-------+ 2 rows in set (0.38 sec)
クエリの仕組みを解説
このクエリが正しく動作する理由を、処理の流れに沿って説明します。
① GROUP BYで値ごとにグループ化
group by Valueによって、同じ値を持つ行がひとつのグループにまとめられます。上記の例では、10・20・30・40・50という5つのグループが作られます。
② HAVING句で件数が2以上のグループだけを残す
having count(*) > 1により、各グループ内の行数を数え、2件以上あるグループのみを出力対象とします。結果として、重複していた「10」と「30」だけが抽出されました。
③ WHERE句との違い
WHERE句はグループ化される前の個々の行に対してフィルターをかけますが、HAVING句はグループ化した後の集計結果に対して条件を指定できます。「重複しているかどうか」という集計条件には必ずHAVING句を使いましょう。
補足:実務での注意点
本記事の例ではselect *fromを使用していますが、MySQLの「ONLY_FULL_GROUP_BY」モードが有効な環境ではエラーになる場合があります。実務では、次のようにGROUP BYで指定した列のみを選択するのが安全です。
SELECT Value FROM DemoTable GROUP BY Value HAVING COUNT(*) > 1;
このように、GROUP BYとHAVING、COUNT(*)を組み合わせるだけで、重複データの検出を簡単に行うことができます。データクレンジングや整合性チェックの際にぜひ活用してください。
-
MySQLでn番目に高い値を取得する方法をわかりやすく解説
MySQLでn番目に高い値を取得する方法MySQLでテーブル内のn番目に高い値を取得したい場合、ORDER BY句とLIMIT句を組み合わせることで簡単に実現できます。基本構文n番目に高い値を選択するための基本的な構文は以下の通りです。SELECT DISTINCT(カラム名) FROM テーブル名 ORDER BY カラム名 DESC LIMIT (n番目の値 - 1), 1;ポイントはLIMIT句の使い方です。第1引数に「(n番目 - 1)」を指定することで、降順に並べ替えた結果から指定した位置のレコードを1件だけ取得できます。また、DISTINCTを使用することで、重複する値を除外した上
-
MySQLでWHERE IN句とNULLを組み合わせてレコードを取得する方法
MySQLでは、WHERE IN句を使った検索時にNULL値を含む行も取得したいケースがあります。しかし、NULLは通常の比較演算子では正しく評価されないため、IS NULLを組み合わせる必要があります。本記事では、その具体的な方法をサンプルコードとともに解説します。基本の構文NULLを含めて検索する場合の基本的な構文は以下のとおりです。ポイントは、IN句の条件に加えて OR カラム名 IS NULL を追加することです。SELECT yourColumnName1, yourColumnName2, yourColumnName3, ... N FROM yourTabl