DISTINCTと重複: 一覧・カテゴリ・ユニーク数を理解する
Stage 1 — 第4章 | データ分析基礎カリキュラム 推定学習時間:30〜40分 | 難易度:★★☆☆☆
この章で学ぶこと
データ分析では、「何件あるか」だけでなく「何種類あるか」を確認する場面がよくあります。 注文は1,000件あっても、購入した顧客は300人かもしれません。 商品明細は5,000行あっても、商品カテゴリは10種類だけかもしれません。
この章では、重複を取り除く DISTINCT を学びます。
この章を終えると、こんなことができるようになります:
- 列の重複を取り除いて一覧を作れる
- 行数とユニーク数の違いを説明できる
DISTINCTが複数列に対してどう働くか理解できる- カテゴリ確認やデータ品質チェックの入口を作れる
1. 重複は悪いものとは限らない
まず押さえたいのは、重複そのものが必ず悪いわけではないということです。
orders テーブルでは、同じ customer_id が何度も出てくることがあります。
これは、同じ顧客が複数回注文しているだけなので自然です。
| order_id | customer_id | order_date | total_amount |
|---|---|---|---|
| 1001 | C001 | 2026-01-05 | 8200 |
| 1002 | C002 | 2026-01-06 | 3500 |
| 1003 | C001 | 2026-01-10 | 12400 |
この例では、注文は3件ですが、顧客は2人です。 分析では、この違いを区別する必要があります。
2. DISTINCTで重複を取り除く
DISTINCT は、同じ値の重複を取り除いて表示します。
SELECT DISTINCT prefecture
FROM customers;
このSQLは、顧客が存在する都道府県の一覧を表示します。 同じ都道府県に複数の顧客がいても、結果には1回だけ表示されます。
商品カテゴリの一覧を確認する場合も同じです。
SELECT DISTINCT category
FROM products;
新しいデータを受け取ったとき、まずカテゴリの種類を確認するのはよい習慣です。 表記ゆれや想定外の値に気づきやすくなります。
3. 行数とユニーク数は違う
次の2つは、似ているようで意味が違います。
SELECT customer_id
FROM orders;
これは注文行ごとの customer_id を表示します。
同じ顧客が複数回注文していれば、同じ customer_id が複数回出ます。
一方、次のSQLは顧客IDの重複を取り除きます。
SELECT DISTINCT customer_id
FROM orders;
これは「注文したことがある顧客の一覧」です。
| 見たいもの | SQLの考え方 |
|---|---|
| 注文件数 | orders の行数を見る |
| 注文した顧客数 | orders の customer_id を重複なしで見る |
| 登録顧客数 | customers の行数を見る |
「注文数」と「購入者数」は違います。 データ分析では、この粒度の違いがとても重要です。
4. 複数列のDISTINCT
DISTINCT は、指定した列の組み合わせに対して重複を取り除きます。
SELECT DISTINCT
customer_id,
status
FROM orders;
これは、customer_id と status の組み合わせの一覧を作ります。
同じ顧客でも、completed と cancelled の両方があれば、それぞれ別の行として表示されます。
商品カテゴリと商品名の組み合わせを見る例です。
SELECT DISTINCT
category,
product_name
FROM products;
この場合、category だけが同じでも、product_name が違えば別行です。
DISTINCT は「各列を個別に重複排除する」のではなく、「選んだ列全体の組み合わせで重複排除する」と覚えましょう。
5. DISTINCTとORDER BYを組み合わせる
一覧を作るときは、並び順をつけると確認しやすくなります。
SELECT DISTINCT category
FROM products
ORDER BY category ASC;
都道府県の一覧も、並べて表示すると表記ゆれを見つけやすくなります。
SELECT DISTINCT prefecture
FROM customers
ORDER BY prefecture ASC;
たとえば、東京, 東京都, Tokyo のような値が混ざっていると、集計時に別カテゴリとして扱われてしまいます。
DISTINCT は、こうしたデータ品質の確認にも使えます。
6. ユニーク数を数える考え方
「一覧を見たい」のではなく、「何種類あるか」を知りたい場合があります。
そのときは、集計関数の COUNT と組み合わせて考えます。
SELECT COUNT(DISTINCT customer_id) AS unique_customers
FROM orders;
これは、注文したことがある顧客の人数を数えるSQLです。
SELECT COUNT(DISTINCT category) AS category_count
FROM products;
これは、商品カテゴリが何種類あるかを数えます。
COUNT(DISTINCT ...) は、実務で非常によく使います。
ただし、詳しい集計関数は次のStageで扱うため、この章では「ユニークな値を数える方法がある」と理解しておけば十分です。
7. DISTINCTを使う前に考えること
DISTINCT は便利ですが、何でも重複排除すればよいわけではありません。
重複している理由を考えることが重要です。
| 重複しているもの | よくある理由 | 消してよいか |
|---|---|---|
orders.customer_id |
同じ顧客が複数回注文している | 目的による |
order_items.order_id |
1注文に複数商品が入っている | 目的による |
products.product_name |
同名商品の登録、表記ゆれ | 要確認 |
customers.customer_id |
顧客マスタでIDが重複 | 異常の可能性 |
たとえば order_items で同じ order_id が複数行あるのは自然です。
1つの注文に複数の商品が含まれるからです。
一方で、customers の customer_id が重複しているなら、データ設計や取り込みに問題があるかもしれません。
8. 実務での使いどころ
カテゴリの一覧を確認する
SELECT DISTINCT category
FROM products
ORDER BY category;
分析前にカテゴリの種類を確認します。
注文経験のある顧客一覧を作る
SELECT DISTINCT customer_id
FROM orders
WHERE status = 'completed';
完了注文を持つ顧客だけのリストです。 キャンペーン対象者の抽出などに使えます。
ステータスの値を確認する
SELECT DISTINCT status
FROM orders
ORDER BY status;
completed, cancelled, pending など、実際にどんな値があるかを確認します。
想定外の値があれば、集計条件を見直す必要があります。
実務での使いどころ: 重複は消す前に理由を見る
DISTINCT は重複を取り除く便利な構文ですが、実務では「重複しているように見える理由」を先に確認します。 同じ顧客IDが複数行ある場合、それはデータの誤りではなく、同じ顧客が複数回注文しているだけかもしれません。
SELECT
customer_id,
COUNT(*) AS order_count
FROM orders
GROUP BY customer_id
ORDER BY order_count DESC;
このSQLは、顧客ごとの注文件数を確認します。
同じ customer_id が何度も出ている理由が「複数注文」なら、DISTINCTで消すのではなく、購入回数として活用できます。
| 重複に見えるもの | まず確認すること |
|---|---|
| 顧客IDが複数回出る | 複数注文・複数行動ではないか |
| 商品IDが複数回出る | 複数注文で買われているだけではないか |
| 注文IDが複数回出る | 注文明細単位のデータではないか |
| 完全に同じ行が複数ある | 取り込みや連携の重複ではないか |
DISTINCT は結果を整える道具です。 原因を見ずに使うと、分析に必要な行まで消してしまうことがあります。
ミニ演習
次の状況で、DISTINCTを使う前に何を確認すべきか考えてください。
ordersで同じcustomer_idが複数回出る。order_itemsで同じproduct_idが複数回出る。- JOIN後に同じ
order_idが複数回出る。 - 顧客数を数えるために
COUNT(DISTINCT customer_id)を使うべき場面を説明する。
まとめ
| 構文 | 意味 | 例 |
|---|---|---|
DISTINCT |
重複を取り除く | SELECT DISTINCT category |
複数列の DISTINCT |
列の組み合わせで重複排除 | DISTINCT customer_id, status |
COUNT(DISTINCT ...) |
ユニーク数を数える | COUNT(DISTINCT customer_id) |
ORDER BY との併用 |
一覧を確認しやすくする | ORDER BY category |
この章のキーメッセージ:
重複は、データの粒度を理解するための重要な手がかりです。DISTINCT は重複を消す道具ではなく、「何種類あるか」「どの粒度で見ているか」を確認する道具として使いましょう。
この章の確認
ordersに同じcustomer_idが複数回出るのは、なぜ自然なことがありますか?- 商品カテゴリの一覧を重複なしで表示するSQLを書いてください。
SELECT DISTINCT customer_id, status FROM orders;は、何の重複を取り除いていますか?- 行数とユニーク顧客数の違いを、注文データの例で説明してください。