0Pricing
SQL Interview Prep · レッスン

一意性におけるDISTINCTとGROUP BYの違い

DISTINCTを使うべき場合と、面接官がGROUP BYを期待する場合を学びます。

「一意性におけるDISTINCTとGROUP BYの違い」はCoddyKit上の無料SQL Interview Prepレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Interview Prep学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Interview Prepコースには全4レッスンが含まれています。

DISTINCTの動作

DISTINCTは重複する行を削除します。面接で確認される重要な点は、1つの列ではなく、選択した行全体に対して作用することです。つまり、SELECT DISTINCT a, bでは(a, b)の組み合わせが重複排除されます。

SELECT DISTINCT department
FROM employees;

DISTINCTは選択したすべての列に適用される

複数の列を指定すると、DISTINCTは一意な組み合わせをそれぞれ残します。つまり、(department, job_title)の組み合わせごとに1行になります。1つの列だけを重複排除する標準的な方法はありません。

SELECT DISTINCT department, job_title
FROM employees;

GROUP BYの動作

GROUP BYは、同じキーを持つ行を1つのグループにまとめ、グループごとに1行にします。単独で1列をGROUP BYすると、その列に対するDISTINCTと同じ結果になります。

SELECT department
FROM employees
GROUP BY department;
-- equivalent to:
SELECT DISTINCT department
FROM employees;

本当の違い:集約

では、両者が異なるのはどんなときでしょうか。集約が必要なときです。GROUP BYではグループごとにCOUNT、SUM、AVGを計算できますが、DISTINCTではできません。一意な行が必要ならDISTINCT、グループごとの指標が必要ならGROUP BYを使います。

SELECT department, COUNT(*) AS headcount
FROM employees
GROUP BY department;

DISTINCTではグループごとの集計はできない

DISTINCTに集計を追加することはできません。「部署ごとの従業員数」のような処理には、SELECT DISTINCTではなく、COUNT(*)とGROUP BYを使うのが正しい方法です。

-- WRONG intent: this errors or returns one total row
-- SELECT DISTINCT department, COUNT(*) FROM employees;

-- RIGHT:
SELECT department, COUNT(*) AS headcount
FROM employees
GROUP BY department;

COUNT(DISTINCT)で両方の考え方を組み合わせる

よく使われる組み合わせがCOUNT(DISTINCT col)です。各グループ内の一意な値を数えられます。ここではDISTINCTを集約関数の中に置き、「部署ごとに異なる役職名はいくつあるか」という問いに答えています。

SELECT department,
       COUNT(DISTINCT job_title) AS distinct_titles
FROM employees
GROUP BY department;

全体で一意な値を数える

GROUP BYを使わない場合、COUNT(DISTINCT col)はテーブル全体の一意な値を数えます。「異なる部署はいくつあるか」という問いに対する、簡潔な答えです。

SELECT COUNT(DISTINCT department) AS n_departments
FROM employees;

-- equivalently, count the deduped subquery
SELECT COUNT(*)
FROM (SELECT DISTINCT department FROM employees) d;

パフォーマンスに大差がないことが多い

DISTINCTとGROUP BYではどちらが速いのでしょうか。単純な重複排除であれば、通常は同等です。オプティマイザが同じような実行計画を作るためです。意図に応じて、一意な行にはDISTINCT、集約にはGROUP BYを選びます。

DISTINCTとNULL

DISTINCTはNULLをどのように扱うのでしょうか。すべてのNULLを等しいものとして扱うため、多数のNULL行は1行にまとめられます。GROUP BYも同じで、NULLは1つのグループを形成します。

-- If manager_id has several NULLs, this returns one NULL row
SELECT DISTINCT manager_id
FROM employees;

PostgresのDISTINCT ON(応用)

応用として、Postgresには標準外のDISTINCT ON (expr)があります。ORDER BYで指定した順序に基づき、キーごとに先頭の行を残します。移植性のあるコードでは、代わりにROW_NUMBER()を使います。

-- Postgres only: latest order per customer
SELECT DISTINCT ON (customer_id) customer_id, order_id, order_date
FROM orders
ORDER BY customer_id, order_date DESC;

DISTINCTは1つの列ではなくSELECT全体に適用される

もう1つの落とし穴です。DISTINCTは行全体に作用するため、SELECT DISTINCT customer_id, order_dateでは顧客ごとに1行にはなりません。その場合は、MAXを使うGROUP BYまたはウィンドウ関数を使用します。

-- Does NOT give one row per customer
SELECT DISTINCT customer_id, order_date FROM orders;

-- One row per customer: latest order date
SELECT customer_id, MAX(order_date) AS last_order
FROM orders
GROUP BY customer_id;

確認問題

適切なツールを選びましょう。

まとめ

まとめると、DISTINCTは行全体の重複を排除し、GROUP BYはキーごとに行をまとめて集約を可能にします。COUNT(DISTINCT col)は一意な値を数え、どちらもNULLを1つとして扱います。パフォーマンスには通常大差ありません。

よくある質問

「一意性におけるDISTINCTとGROUP BYの違い」レッスンは無料ですか?

はい。「一意性におけるDISTINCTとGROUP BYの違い」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Interview Prepコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Interview Prepコースには全4レッスンが含まれています。

「一意性におけるDISTINCTとGROUP BYの違い」で何を学びますか?

DISTINCTを使うべき場合と、面接官がGROUP BYを期待する場合を学びます。 ブラウザで直接実行するハンズオンコードでSQL Interview Prepを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

SQL Interview Prepを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSQL Interview Prepは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「一意性におけるDISTINCTとGROUP BYの違い」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSQL Interview Prepレッスンでコードを書いて実行できますか?

はい。すべてのSQL Interview Prepレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 列の射影とエイリアスの落とし穴
  2. 計算列と式の優先順位
  3. 一意性におけるDISTINCTとGROUP BYの違い
  4. SELECT内のCASE式
← SQL Interview Prepに戻る