単なる重複削除機能の観点からの違いは何ですか
とは異なり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
このトピックについてブログの投稿で詳しく説明しました