PostgreSQL の DISTINCT 句
このチュートリアルでは、さまざまなコード例を使用して DISTINCT
句の使用法を説明します。 また、テーブル全体と特定の属性セットに対してこの句を使用する方法も示します。
PostgreSQL の DISTINCT
句の紹介
テーブルのすべての行を表示したい場合は、単純な SELECT
ステートメントを使用できることがわかっています。 したがって、次のテーブルがあると仮定しましょう。
Create table sample ( Number int not null);
それでは、このサンプル テーブルにデータを挿入してみましょう。
Insert into sample values (100), (200), (300), (100);
このデータベースで単純な SELECT * FROM sample
クエリを実行すると、すべての行を表示する次の出力が得られます。
ここで何が起こっているか分かりますか? 値 100
は、挿入中に繰り返されたため、2 回出力されています。 一意の値を表示したい場合はどうすればよいでしょうか? PostgreSQLでこれを行う方法はありますか?
はい、DISTINCT
句を使用すると、クエリの結果から重複を除外し、それらを 1 回だけ表示できます。 以下、PostgreSQLのDISTINCT
とDISTINCT ON
について詳しく学びましょう。
PostgreSQL での DISTINCT
句の使用
SELECT
ステートメントの DISTINCT
句は、結果からすべての重複する行の値を削除します。 出力で値が繰り返されないように、同一の値から 1つだけが表示されます。
上で定義した sample
テーブルに適用して DISTINCT
句の構文を調べてみましょう。
SELECT DISTINCT * FROM sample;
このクエリを実行すると、以下の出力が得られます。
違いに気づきましたか? 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;
を実行するとします。 クエリを実行すると、すべての行を表示する次の出力が得られます。
期待どおり、100
の値が繰り返されていることがわかります。 上記で学んだように、DISTINCT
句を使用してみましょう。
SELECT DISTINCT * FROM example;
うまく行かなかった! 私たちはまだ同じ出力を得ています。 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;
次の出力が得られます。
100
の重複値はなくなりました! したがって、予想どおり、繰り返し値 number
を持つ最初の行のみが出力に表示されていることがわかります。 重要な点は、最初の行が常に予測可能であるとは限らないということです。
これは、クエリが実行されるたびに異なる出力を返す可能性があることを意味し、これが問題になる可能性があります。 したがって、ORDER BY
句と一緒に使用することをお勧めします。
ORDER BY
句を使用すると、テーブルの 1つまたは複数の属性に基づいてデータを並べ替えることができます。 その一連の属性を使用して、降順または昇順で並べ替えることができます。
次のクエリを使用して、ORDER BY
句を DISTINCT ON
句と一緒に使用する方法を見てみましょう。
SELECT DISTINCT ON (number) * FROM example
ORDER BY number, id DESC;
このクエリを実行すると、次の出力が得られます。
最後の行が唯一の繰り返し発生として表示されていることがわかります。
id
に従って行を降順に並べたので、id
が 4
である最後の行が最初に表示され、最初の出現として扱われます。
ただし、id
に従って行を並べ替えたいと思っていたにもかかわらず、ORDER BY
句の最初の属性として number
を指定したことに気付いたはずです。
PostgreSQL では、ORDER BY
句で指定された左端の属性が、DISTINCT ON
句で記述された属性と一致する必要があります。 これは PostgreSQL の単なる要件です。
これを分析すると、左端の属性が同じ値を持つため、重複行の結果が妨げられないことがわかります。 したがって、行は次の属性に従って自動的に並べ替えられます。
この場合、number
の正確な値は 100
であったため、行は次の属性、つまり id
に従って並べ替えられました。 エラーが発生することがわかっている次のクエリを実行してみましょう。
SELECT DISTINCT ON (number) * FROM example
ORDER BY id DESC;
予想どおり、次のエラーが発生します。
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