この記事では、SQLのDISTINCT句について基本的な使い方からCOUNTとの併用、GROUP BYとの違い、複数列での活用法まで解説します。重複データ処理の方法を理解でき、効率的なSQL記述やデータ抽出の悩みを解決できる内容です。
目次
SQLのDISTINCTとは
SQLのDISTINCTは、データベースからデータを取得する際に重複する行を取り除き、ユニークな結果のみを返すために使用されるキーワードです。特に大量のデータを扱う業務において、同じ値が繰り返し格納されている場合に「一意なリスト」を抽出したいケースで役立ちます。
たとえば、顧客テーブルから「顧客が居住している都道府県の一覧」を取得したい場合、全顧客データを集計するのではなく、重複を取り除いた形で表示できます。
DISTINCTでできること
DISTINCTを利用することで実現できることは以下のとおりです。
- 特定の列における値の重複を取り除き、一意な値を一覧化できる
- 複数列を組み合わせ、一意なレコードの組み合わせを取得できる
- レポートやダッシュボード作成時に、必要以上に同じデータを繰り返し表示しないように整理できる
つまり、DISTINCTを用いると、データの冗長さを排除し、シンプルかつ見やすい出力を得られる点が大きなメリットです。
特にデータ分析やBI(ビジネスインテリジェンス)ツールに取り込む前処理として利用されることも多く、SQLにおける基本的かつ重要な機能です。
GROUP BYとの違い
DISTINCTと似た機能を持つSQLの句にGROUP BYがありますが、両者には明確な違いがあります。
- DISTINCTは「重複を排除して一意な行を返す」ことが目的
- GROUP BYは「特定の列や条件で結果をグループ化」し、集計関数(COUNT, SUM, AVG など)と一緒に使うことが前提
例えば「顧客の居住する都道府県一覧」を取得する場合にはDISTINCTが適しています。一方で「都道府県ごとの顧客数を集計したい」といったケースではGROUP BYが必要になります。
すなわち、DISTINCTはシンプルに重複を取り除くためのキーワードであり、GROUP BYは集計処理に直結する機能として使い分けることが重要です。
DISTINCTの基本的な使い方
SELECT DISTINCTの基本構文
SQLにおいてDISTINCTは、重複したデータを排除してユニークな結果を取得するためのキーワードです。もっとも一般的に使われるのは、SELECT DISTINCT
構文です。この構文を使うと、指定した列や複数列の組み合わせにおいて重複を取り除いた結果セットが返されます。基本的な構文は以下のようになります。
SELECT DISTINCT 列名1, 列名2, ...
FROM テーブル名;
このように記述することで、指定した列のユニークな値を抽出でき、データ分析やレポート作成において非常に有効です。
単一列でのDISTINCTの使用例
単一列に対してsql distinctを適用する場合は、重複しているレコードを排除し、ユニークな値だけを抽出することができます。例えば、社員が所属する部署コードの一覧を取得したい場合に便利です。
SELECT DISTINCT 部署コード
FROM 社員マスタ;
このクエリを実行すると、同じ部署に複数人が所属していても、結果セットには重複のない部署コードだけが並びます。つまり、どの部署が存在しているのかを把握する際に効果的な方法です。
複数列でのDISTINCTの使用例
複数列を対象にsql distinctを使う場合は、それらの列の組み合わせに対して重複を排除します。これは、単一列のユニークさだけでなく、「列のペア」や「複数列の組み合わせ」が固有であるケースを抽出するのに役立ちます。
SELECT DISTINCT 部署コード, 役職
FROM 社員マスタ;
この場合、同じ部署コードでも役職が異なれば別の行として扱われます。たとえば「営業部の課長」と「営業部の部長」は異なる組み合わせとして結果に含まれ、一方で全く同じ部署コードと役職のデータは1行にまとめられます。
レコード全体での重複排除
DISTINCTを全ての列に対して適用することで、行全体の重複を取り除くことが可能です。この場合、テーブル内でまったく同じ内容の行が複数登録されていると、それらは1行にまとめられます。
SELECT DISTINCT *
FROM 売上データ;
この例では、同一の商品や金額、日付といった全列が一致するレコードは1行として返されるため、完全にユニークなレコード一覧を取得できます。ただし、テーブルの列数が多い場合は処理コストが高くなる点に注意が必要です。
COUNT関数との組み合わせ
DISTINCTはCOUNT
関数と組み合わせることで、ユニークな値の数を集計する用途にも活用されます。重複を除いた件数を求めたい場合は必須のテクニックです。
単一列をDISTINCTでカウントする場合
例えば、社員が所属する部署の数を知りたい場合、以下のようなクエリを使います。
SELECT COUNT(DISTINCT 部署コード) AS 部署数
FROM 社員マスタ;
これにより、部署コードのユニーク数が返され、組織に存在する部署の総数を簡単に把握できます。
複数列をDISTINCTでカウントする場合
複数列の組み合わせが一意となる件数を求めることも可能です。例えば部署と役職の組み合わせのパターン数を求めたい場合は以下のようになります。
SELECT COUNT(DISTINCT 部署コード, 役職) AS 組み合わせ数
FROM 社員マスタ;
この結果は、部署ごとにどの役職が存在するのか、全体としていくつの組み合わせがあるのかを把握するのに役立ちます。ビジネス上では組織構造の分析や役職配置の調査に応用できます。
DISTINCTの応用的な使い方
他のSQL句や関数との組み合わせ
SQLのDISTINCTは、単純に重複データを排除するだけでなく、他のSQL句や関数と組み合わせることで、より柔軟なデータ抽出が可能になります。特に、JOIN
句やWHERE
句、集計関数と活用する場面では、データの正確性や効率性に直結するため重要です。
- JOIN句との組み合わせ: 複数のテーブルを結合した際にレコードが重複することがあります。そこで
DISTINCT
を利用すると、重複行を排除したユニークな組み合わせのみを取得可能です。 - WHERE句との組み合わせ: 条件を絞り込んだ上で、一意の値のみを取り出したい場合に有効です。例えば、特定地域の顧客リストから重複を排除して抽出するケースなどです。
- 集計関数との組み合わせ:
DISTINCT
はCOUNT
やSUM
と組み合わせることで、ユニークな値に対する集計が可能になります。これにより、単なる全件カウントではなく「重複しないデータ数」を把握できます。
このように、DISTINCTは他のSQL要素と組み合わせることでデータ品質を高め、より実務的なクエリ設計に役立ちます。ただし、複数の句や関数と一緒に使用するとパフォーマンスへの影響が大きくなるため、実行計画を確認しつつ設計することが推奨されます。
DISTINCTとORDER BYの関係
ORDER BY
とDISTINCT
はよく組み合わせて利用されますが、クエリの解釈や結果セットの順序に影響するため理解が必要です。DISTINCT
は重複排除のためにまず対象列の組み合わせを算出し、その後にORDER BY
で並び替えを行います。
- 利用順序:
DISTINCT
で抽出後にORDER BY
が処理されるため、ソート対象に含まれない列をORDER BY
に直接指定することはできません。 - 実務的な注意点: 場合によってはソート対象列を
SELECT DISTINCT
の対象に含める必要があります。含めないと構文エラーや意図しない結果になるケースがあります。
つまり、DISTINCTとORDER BYを併用する際には「SELECT句に必要な列を明示的に書く」点が非常に重要です。
DISTINCTとGROUP BYの関係
DISTINCT
とGROUP BY
はどちらも「重複排除」の結果を得られるため混同されやすいですが、目的と処理方法が異なります。
- DISTINCT: 単純にユニークなレコードを返す。
- GROUP BY: データをグループ化し、その上で集計を行う。
例えば「都道府県ごとの顧客数」を調べたい場合、GROUP BY
を使うのが適切です。一方で「データベースに登録されている都道府県の一覧」を取得したいだけならDISTINCT
が向いています。
用途に応じてどちらを用いるかを適切に選ぶことで、クエリの表現力と処理効率を大幅に高めることができます。
大文字小文字とDISTINCTの挙動
SQLでDISTINCT
を使う場合、データベースごとに大文字と小文字の扱いが異なる点に注意が必要です。例えば、MySQLではデフォルトで大文字と小文字を区別しない照合順序(collation)が使われることが多いため、「Tokyo」と「TOKYO」は同一とみなされます。一方で、PostgreSQLでは標準的に大文字と小文字を区別するため、両者は異なる値として扱われます。
- MySQL: collationの設定次第で挙動が変わる。
- PostgreSQL: デフォルトでcase-sensitive(区別あり)。
- SQL Server: データベースやカラムのcollation設定で異なる挙動が発生。
そのため、DISTINCTを使う際には必ずシステムの照合順序設定を確認し、必要であれば明示的にCOLLATE
句を指定することが推奨されます。
DISTINCTとトランザクション処理
DISTINCT
は読み取り専用の操作であるため、そのものがトランザクションの整合性を直接破壊することはありません。ただし、同時実行制御やロックの観点からは注意すべきポイントがあります。
- 一貫性の確保: トランザクション内で
DISTINCT
を使う場合、並列実行中の更新によって結果が変わる可能性があります。適切な隔離レベル(ISOLATION LEVEL)を設定することが重要です。 - パフォーマンスの影響: 大規模テーブルに対する
SELECT DISTINCT
はソートやハッシュ処理を伴うため、ロック時間が増加し、他のトランザクションに遅延を与える場合があります。 - 実践的な工夫: ビジネスロジックで必須ではない場合、DISTINCTの適用はバッチ処理など負荷の少ない時間帯に行うのが望ましいです。
すなわち、DISTINCT
自体は便利な機能ですが、同時実行環境ではトランザクション設計とあわせて考える必要がある点を忘れてはいけません。
データベースごとのDISTINCTの書き方と使い方事例
MySQLでのDISTINCT使用例
単一列での重複排除
MySQLでは、SELECT DISTINCT
を利用することで、特定の列に存在する重複データを一意に抽出できます。例えば、顧客テーブルに同じ地域が複数回記録されている場合でも、DISTINCT
を適用すれば地域ごとに一つの値を取得することが可能です。これにより、重複データを手軽に整理できるため、レポート作成やデータ分析の効率が向上します。
SELECT DISTINCT region
FROM customers;
この例では、「customers」テーブルの「region」列から重複を排除し、存在する地域ごとの一覧を取得できます。
複数列での重複排除
MySQLでは複数列に対してもDISTINCT
を適用できます。複数列を指定した場合、それらの列の組み合わせが完全に一致する行のみが重複とみなされます。そのため、単一列とは異なり、より細やかなデータの一意性を確保することができます。
SELECT DISTINCT region, city
FROM customers;
この例では、「region」と「city」の組み合わせが重複しないようにデータを抽出します。同じ地域に複数の都市が含まれている場合でも、都市名との組み合わせが異なれば別のレコードとして扱われるため、分析対象を精緻化できます。
MySQLでのsql distinct
活用は、データの重複排除だけでなく、ユニークな組み合わせを効率良く取得できるという点で非常に有効です。
PostgreSQLでのDISTINCT使用例
単一列での重複排除
PostgreSQLでもSELECT DISTINCT
の基本的な使い方はMySQLと同じです。例えば、社員テーブルから役職の一覧を取得する際、重複を除外することでユニークな役職名だけを取り出すことが可能です。
SELECT DISTINCT position
FROM employees;
このクエリでは「employees」テーブルの「position」列から異なる役職名だけを抽出し、重複を省いたシンプルな結果を返します。
複数列での重複排除
PostgreSQLでも複数列に対してDISTINCT
を適用することで、列の組み合わせごとの一意な値を取得可能です。特にPostgreSQLはDISTINCT ON
という独自の拡張構文を提供しており、複数列に対する柔軟な利用が可能です。
SELECT DISTINCT ON (department) department, employee_name
FROM employees
ORDER BY department, hire_date DESC;
この文では「department」ごとに一人だけ社員を抽出し、さらに採用日の降順で並べることで最も新しい社員を取り出しています。これにより、一般的なDISTINCT
よりも高度なデータ取得が実現できます。
SQL ServerでのDISTINCT使用例
SQL ServerでもSELECT DISTINCT
を利用して重複を排除できます。基本的な構文は他のRDBMSと同じで、単一列・複数列ともに対応しています。例えば、販売データから顧客IDの一覧を取り出す場合や、顧客IDと購入商品の組み合わせをユニークに抽出する場合に有用です。
SELECT DISTINCT customer_id
FROM sales;
また、複数列を指定することで、顧客IDと商品IDの組み合わせを一意に取得でき、ユニークな購買パターンを分析することが可能になります。
SnowflakeでのDISTINCTやIS DISTINCT FROMの活用事例
SnowflakeではDISTINCT
に加え、IS DISTINCT FROM
という条件式を利用できるのが特徴です。これは通常の=
や<>
と異なり、NULL値を正確に比較できるという利点があります。NULLが含まれる列の比較においては、通常のSQLでは意図した結果が得られないことが多いため、Snowflake特有のこの構文は非常に有効です。
SELECT *
FROM orders a
WHERE a.order_date IS DISTINCT FROM a.ship_date;
このクエリでは、注文日と出荷日が異なる行を取得します。NULLを含む場合でも正しく判定されるため、欠損値を含むデータ分析において便利です。
InterSystems SQLでのDISTINCTの取り扱い
InterSystems SQLでもDISTINCT
は標準SQLと同じように利用できます。基本的には単一列や複数列の重複を排除する仕組みが用意されており、医療情報システムや大規模データベースにおいてユニークな値の一覧を効率的に取り出す際に活用されます。特にInterSystems IRISなどではパフォーマンス最適化が重視されており、DISTINCT
の結果を利用することで、重複のないデータセットを前処理として準備できるのが大きな強みです。
SELECT DISTINCT PatientID, DiagnosisCode
FROM MedicalRecords;
この例では、患者IDと診断コードの組み合わせをユニークに取得できるため、重複を排除して効率的に分析可能な形に整えることができます。
DISTINCTを使う際の注意点と代替手法
パフォーマンスへの影響
SQLのDISTINCT
は重複データの排除に便利な構文ですが、仕組みとしては検索結果の全行を比較・ソートした上で重複を削除するため、特に大規模データセットではパフォーマンスに影響を及ぼすことがあります。
インデックスの活用や対象列数の削減ができない場合、クエリ実行時間やメモリ消費が増大する可能性が高いです。そのため、必要以上にDISTINCT
を多用すると、レスポンス速度の低下やデータベースへの負荷増大につながります。
実運用環境においては「とりあえずDISTINCTをつける」という使い方を避け、実行計画を確認しながら慎重に利用することが推奨されます。
DISTINCTを多用しないほうが良いケース
次のようなケースでは、DISTINCT
を使わず、別のアプローチを検討した方が良い場合があります。
- テーブル結合の設計不備によって同じデータが重複している場合
→ 根本的にJOIN条件を見直すべきであり、DISTINCT
で後処理するのは本質的解決ではありません。 - データ選択ロジックが曖昧で、不要なカラムまで取得している場合
→ 必要な列に限定したSELECTを行うことで、重複の発生自体を抑制できます。 - 分析目的で集計処理を行うケース
→ 単純な重複排除よりも、条件付き集計の方が業務要件に沿った結果が得られることがあります。
このように、DISTINCT
を多用するとパフォーマンスだけでなく、クエリ設計そのものの質が低下するリスクがあるため注意が必要です。
DISTINCTの代替手法(GROUP BYやウィンドウ関数など)
DISTINCT
の代わりに、以下のような手法を用いることで、より効率的かつ用途に応じた柔軟な結果が得られる場合があります。
- GROUP BY
特定の列で重複を排除しながら集計結果も同時に取得できます。例えば、顧客ごとの注文件数を求める際にはGROUP BY customer_id
を使うことで、重複排除と集計を一度に実現できます。 - ウィンドウ関数(ROW_NUMBERなど)
データごとに順位を付与し、最新1件や特定条件の行だけを抽出することが可能です。これにより、単純なDISTINCT
では実現できない「重複の中から代表値を選ぶ」処理が行えます。 - EXISTSやINサブクエリ
テーブルの存在確認によるフィルタリングで、重複を発生させずに効率的な検索を行えます。
これらの代替手法を活用することで、SQLの可読性と実行効率が向上し、業務要件に即した結果を得やすくなります。特に大規模なデータ分析やトランザクション処理が多いシステムでは、DISTINCT
の安易な利用を避け、適切な手法を選択することが重要です。
まとめ
本記事では、SQLにおけるDISTINCT
の基本から応用、そしてデータベースごとの使い方や注意点について解説しました。DISTINCT
は重複を排除してデータを取得するためのシンプルかつ強力な構文であり、分析やレポーティングにおいて非常に役立つテクニックです。しかし同時に、パフォーマンスへの影響や代替手法の検討も必要であるため、場面に応じた最適な使い分けを意識することが重要です。
特に重要なポイントは以下の通りです。
SELECT DISTINCT
は、単一列・複数列・レコード全体に対して適用可能で汎用性が高い。COUNT(DISTINCT ...)
を利用することで、ユニークな値の数を効率的に取得できる。GROUP BY
との違いや組み合わせによって、より柔軟な集計や分析が可能。- データベース製品ごとに若干の挙動や追加機能が異なるため、利用環境に応じた理解が必要。
- 乱用はパフォーマンス低下につながるため、必要に応じてウィンドウ関数やサブクエリなど代替手法も検討すべき。
sql distinct
は、日常的に利用される基本構文である一方で、奥が深く多彩な使い道があります。正しい理解と実践的な使い分けを行うことで、データ分析やシステム開発において効率的なクエリ設計が可能となるでしょう。