重複を扱う — DISTINCT と GROUP BY

SQLで重複データを扱う方法を解説します。DISTINCTによる重複除去、GROUP BYとの違いと使い分け、重複行を見つける方法まで、具体例で整理します。

同じ値が何度も現れる「重複」は、データを扱ううえで避けて通れません。SQL には重複を取り除く手段がいくつかあり、場面によって使い分けます。ここでは DISTINCTGROUP BY を中心に整理します。

DISTINCT で重複を取り除く

もっとも手軽なのが DISTINCT です。SELECT の直後に付けると、結果から重複行を取り除きます。

query.sql
SELECT DISTINCT dept
FROM employees;

これは「登場する部門の一覧」を、重複なしで返します。複数の列を指定すると、その列の組み合わせが重複しているかで判定します。

query.sql
SELECT DISTINCT dept, hire_year
FROM employees;

この場合、「部門と入社年の組み合わせ」が同じ行がまとめられます。片方だけでなく、指定した全列の組で見る点に注意してください。

DISTINCT と GROUP BY の違い

重複を除くだけなら、GROUP BY でも同じことができます。

query.sql
SELECT dept
FROM employees
GROUP BY dept;

結果は SELECT DISTINCT dept と同じです。では違いは何かというと、集計するかどうかです。

  • DISTINCT:重複を除くだけ。集計はしない
  • GROUP BY:グループにまとめ、各グループを集計できる

「部門の一覧が欲しいだけ」なら DISTINCT、「部門ごとに人数や平均を出したい」なら GROUP BY を使います。集計が絡むなら GROUP BY、と覚えておくとよいでしょう。

query.sql
-- GROUP BY なら集計を足せる
SELECT dept, COUNT(*) AS 
FROM employees
GROUP BY dept;

重複している行を見つける

「重複しているデータを探したい」ときは、GROUP BYHAVING の組み合わせが定番です。

query.sql
SELECT name, COUNT(*) AS 
FROM employees
GROUP BY name
HAVING COUNT(*) >= 2;

name でグループ化し、HAVING COUNT(*) >= 2 で「2 件以上ある=重複している」ものだけを残します。データの重複チェックやクレンジングの第一歩としてよく使うパターンです。

件数を数えるときの DISTINCT

COUNT の中でも DISTINCT が使えます。「何種類の値があるか」を数えるときに便利です。

query.sql
SELECT COUNT(DISTINCT dept) AS 
FROM employees;

COUNT(dept) は「dept が NULL でない行数」ですが、COUNT(DISTINCT dept) は「異なる部門の種類数」を返します。目的に応じて使い分けます。

まとめ

  • DISTINCT は重複を取り除く(指定した全列の組で判定)
  • 重複を除くだけなら DISTINCT、集計もするなら GROUP BY
  • 重複行を探すには GROUP BYHAVING COUNT(*) >= 2
  • COUNT(DISTINCT 列) で「何種類あるか」を数えられる

重複の扱いは、データの正確さに直結します。「ユニークな一覧が欲しいのか、集計したいのか、重複を見つけたいのか」を意識して手段を選びましょう。

手を動かして確認しましょうブラウザ上で SQL を書いて実行・自動採点できる演習問題に挑戦できます。
問題一覧へ →