PostgreSQL の DISTINCT 句

Bilal Shahid 2023年6月20日
  1. PostgreSQL の DISTINCT 句の紹介
  2. PostgreSQL での DISTINCT 句の使用
  3. PostgreSQL での DISTINCT ON 句の使用
PostgreSQL の DISTINCT 句

このチュートリアルでは、さまざまなコード例を使用して DISTINCT 句の使用法を説明します。 また、テーブル全体と特定の属性セットに対してこの句を使用する方法も示します。

PostgreSQL の DISTINCT 句の紹介

テーブルのすべての行を表示したい場合は、単純な SELECT ステートメントを使用できることがわかっています。 したがって、次のテーブルがあると仮定しましょう。

Create table sample ( Number int not null);

それでは、このサンプル テーブルにデータを挿入してみましょう。

Insert into sample values (100), (200), (300), (100);

このデータベースで単純な SELECT * FROM sample クエリを実行すると、すべての行を表示する次の出力が得られます。

postgresql の個別句 - 出力 1

ここで何が起こっているか分かりますか? 値 100 は、挿入中に繰り返されたため、2 回出力されています。 一意の値を表示したい場合はどうすればよいでしょうか? PostgreSQLでこれを行う方法はありますか?

はい、DISTINCT 句を使用すると、クエリの結果から重複を除外し、それらを 1 回だけ表示できます。 以下、PostgreSQLのDISTINCTDISTINCT ONについて詳しく学びましょう。

PostgreSQL での DISTINCT 句の使用

SELECT ステートメントの DISTINCT 句は、結果からすべての重複する行の値を削除します。 出力で値が繰り返されないように、同一の値から 1つだけが表示されます。

上で定義した sample テーブルに適用して DISTINCT 句の構文を調べてみましょう。

SELECT DISTINCT * FROM sample;

このクエリを実行すると、以下の出力が得られます。

postgresqlのdistinct句 - 出力2

違いに気づきましたか? 100 の値は、単純な SELECT ステートメントで 2 回表示されるのではなく、1 回だけ表示されるようになりました。 これが DISTINCT 句の威力です。

DISTINCT 句の使用法を理解したところで、別のシナリオを紹介しましょう。 次の表があるとします。

Create table example(
    Id int not null,
    Number int not null,
    Constraint PK2 primary key (id)
);

Insert into example values (1, 100), (2, 200), (3, 300), (4, 100);

単純な SELECT * FROM example; を実行するとします。 クエリを実行すると、すべての行を表示する次の出力が得られます。

postgresql の distinct 句 - 出力 3

期待どおり、100 の値が繰り返されていることがわかります。 上記で学んだように、DISTINCT 句を使用してみましょう。

SELECT DISTINCT * FROM example;

postgresql の distinct 句 - 出力 3

うまく行かなかった! 私たちはまだ同じ出力を得ています。 100 の値を持つすべての行は、id とともに全体として扱われる場合、複製されません。

id の値が両方で異なるため、これらは一意であり、出力に表示されます。 では、これをどのように回避しますか?

特定の属性から重複を除外する方法はありますか? はい、DISTINCT ON 句を使用すると、PostgreSQL でこれを行うことができます。

PostgreSQL での DISTINCT ON 句の使用

DISTINCT ON 句を使用すると、最初に出現した値のみを表示することにより、SELECT クエリの結果から指定された属性の重複値を削除できます。

このように、行の他の属性の値が異なっていても、最初に検出された行のみが表示されます。 次の構文があります。

DISTINCT ON (attribute1, attribute2,)

上で定義した example テーブルで次のクエリを実行して、DISTINCT ON 句の構文と動作を理解しましょう。

SELECT DISTINCT ON (number) * FROM example;

次の出力が得られます。

postgresqlのdistinct句 - 出力4

100 の重複値はなくなりました! したがって、予想どおり、繰り返し値 number を持つ最初の行のみが出力に表示されていることがわかります。 重要な点は、最初の行が常に予測可能であるとは限らないということです。

これは、クエリが実行されるたびに異なる出力を返す可能性があることを意味し、これが問題になる可能性があります。 したがって、ORDER BY 句と一緒に使用することをお勧めします。

ORDER BY 句を使用すると、テーブルの 1つまたは複数の属性に基づいてデータを並べ替えることができます。 その一連の属性を使用して、降順または昇順で並べ替えることができます。

次のクエリを使用して、ORDER BY 句を DISTINCT ON 句と一緒に使用する方法を見てみましょう。

SELECT DISTINCT ON (number) * FROM example
ORDER BY number, id DESC;

このクエリを実行すると、次の出力が得られます。

postgresql の distinct 句 - 出力 5

最後の行が唯一の繰り返し発生として表示されていることがわかります。

id に従って行を降順に並べたので、id4 である最後の行が最初に表示され、最初の出現として扱われます。

ただし、id に従って行を並べ替えたいと思っていたにもかかわらず、ORDER BY 句の最初の属性として number を指定したことに気付いたはずです。

PostgreSQL では、ORDER BY 句で指定された左端の属性が、DISTINCT ON 句で記述された属性と一致する必要があります。 これは PostgreSQL の単なる要件です。

これを分析すると、左端の属性が同じ値を持つため、重複行の結果が妨げられないことがわかります。 したがって、行は次の属性に従って自動的に並べ替えられます。

この場合、number の正確な値は 100 であったため、行は次の属性、つまり id に従って並べ替えられました。 エラーが発生することがわかっている次のクエリを実行してみましょう。

SELECT DISTINCT ON (number) * FROM example
ORDER BY id DESC;

予想どおり、次のエラーが発生します。

postgresql の distinct 句 - 出力 6

著者: Bilal Shahid
Bilal Shahid avatar Bilal Shahid avatar

Hello, I am Bilal, a research enthusiast who tends to break and make code from scratch. I dwell deep into the latest issues faced by the developer community and provide answers and different solutions. Apart from that, I am just another normal developer with a laptop, a mug of coffee, some biscuits and a thick spectacle!

GitHub