単なる重複削除機能の観点からの違いは何ですか
とは異なりDISTINCT
、グループごとGROUP BY
にデータを集計できるという事実(他の多くの回答で言及されています)を除けば、私の意見で最も重要な違いは、2つの操作が論理的な順序で2つの非常に異なるステップで「発生」するという事実です。ステートメントで実行される操作の。SELECT
最も重要な操作は次のとおりです。
FROM
( JOIN
、APPLY
などを含む)
WHERE
GROUP BY
(重複を削除できます)
- 集計
HAVING
- ウィンドウ関数
SELECT
DISTINCT
(重複を削除できます)
UNION
、INTERSECT
、EXCEPT
(重複を削除できます)
ORDER BY
OFFSET
LIMIT
ご覧のとおり、各操作の論理的な順序は、その操作で実行できることと、後続の操作にどのように影響するかに影響します。特に、操作が操作 (投影) の「前に発生する」という事実は、GROUP BY
次のことを意味します。SELECT
- プロジェクションに依存しません(これは利点になる可能性があります)
- 投影からの値を使用することはできません (これは欠点になる可能性があります)。
1. 投影法に依存しない
投影に依存しないことが役立つ例は、個別の値でウィンドウ関数を計算する場合です。
SELECT rating, row_number() OVER (ORDER BY rating) AS rn
FROM film
GROUP BY rating
Sakila データベースに対して実行すると、次の結果が得られます。
rating rn
-----------
G 1
NC-17 2
PG 3
PG-13 4
R 5
DISTINCT
同じことは簡単には達成できませんでした:
SELECT DISTINCT rating, row_number() OVER (ORDER BY rating) AS rn
FROM film
そのクエリは「間違って」おり、次のような結果になります。
rating rn
------------
G 1
G 2
G 3
...
G 178
NC-17 179
NC-17 180
...
これは私たちが望んでいたことではありません。DISTINCT
操作は投影の「後に発生する」DISTINCT
ため、ウィンドウ関数は既に計算され、投影されているため、評価を削除することはできません。を使用するDISTINCT
には、クエリのその部分をネストする必要があります。
SELECT rating, row_number() OVER (ORDER BY rating) AS rn
FROM (
SELECT DISTINCT rating FROM film
) f
補足:この特定のケースでは、使用することもできますDENSE_RANK()
SELECT DISTINCT rating, dense_rank() OVER (ORDER BY rating) AS rn
FROM film
2. 投影からの値を使用することはできません
SQL の欠点の 1 つは、場合によっては冗長になることです。前に見たのと同じ理由 (つまり、操作の論理的な順序) で、投影しているものによって「簡単に」グループ化することはできません。
これは無効な SQL です:
SELECT first_name || ' ' || last_name AS name
FROM customer
GROUP BY name
これは有効です (式の繰り返し)
SELECT first_name || ' ' || last_name AS name
FROM customer
GROUP BY first_name || ' ' || last_name
これも有効です (式のネスト)
SELECT name
FROM (
SELECT first_name || ' ' || last_name AS name
FROM customer
) c
GROUP BY name
このトピックについては、ブログ記事で詳しく説明しています