Was ist der Unterschied aus Sicht der Funktionalität zum Entfernen von Duplikaten?
Abgesehen von der Tatsache , dass im Gegensatz zu DISTINCT
, GROUP BY
ermöglicht die Aggregation der Daten pro Gruppe (die von vielen anderen Antworten erwähnt wurde), der wichtigste Unterschied meiner Meinung nach ist die Tatsache , dass die beiden Operationen „passieren“ an zwei sehr unterschiedlichen Schritten in der logischen Reihenfolge von Operationen, die in einer SELECT
Anweisung ausgeführt werden .
Hier sind die wichtigsten Operationen:
FROM
(einschließlich JOIN
, APPLY
usw.)
WHERE
GROUP BY
(kann Duplikate entfernen)
- Aggregationen
HAVING
- Fensterfunktionen
SELECT
DISTINCT
(kann Duplikate entfernen)
UNION
, INTERSECT
, EXCEPT
(Können Duplikate entfernen)
ORDER BY
OFFSET
LIMIT
Wie Sie sehen können, beeinflusst die logische Reihenfolge jeder Operation, was damit gemacht werden kann und wie sie nachfolgende Operationen beeinflusst. Insbesondere bedeutet die Tatsache, dass die GROUP BY
Operation "vor" der SELECT
Operation (der Projektion) stattfindet, dass:
- Es hängt nicht von der Projektion ab (was von Vorteil sein kann)
- Es können keine Werte aus der Projektion verwendet werden (was ein Nachteil sein kann).
1. Es hängt nicht von der Projektion ab
Ein Beispiel, bei dem es nicht sinnvoll ist, von der Projektion abhängig zu sein, ist, wenn Sie Fensterfunktionen für bestimmte Werte berechnen möchten:
SELECT rating, row_number() OVER (ORDER BY rating) AS rn
FROM film
GROUP BY rating
Wenn es mit der Sakila-Datenbank ausgeführt wird , ergibt dies:
rating rn
-----------
G 1
NC-17 2
PG 3
PG-13 4
R 5
Dasselbe konnte nicht einfach erreicht DISTINCT
werden:
SELECT DISTINCT rating, row_number() OVER (ORDER BY rating) AS rn
FROM film
Diese Abfrage ist "falsch" und ergibt so etwas wie:
rating rn
------------
G 1
G 2
G 3
...
G 178
NC-17 179
NC-17 180
...
Das wollten wir nicht. Die DISTINCT
Operation "erfolgt nach" der Projektion, sodass wir DISTINCT
Bewertungen nicht mehr entfernen können, da die Fensterfunktion bereits berechnet und projiziert wurde. Um zu verwenden DISTINCT
, müssten wir diesen Teil der Abfrage verschachteln:
SELECT rating, row_number() OVER (ORDER BY rating) AS rn
FROM (
SELECT DISTINCT rating FROM film
) f
Randnotiz: In diesem speziellen Fall könnten wir auch verwendenDENSE_RANK()
SELECT DISTINCT rating, dense_rank() OVER (ORDER BY rating) AS rn
FROM film
2. Es können keine Werte aus der Projektion verwendet werden
Einer der Nachteile von SQL ist die zeitweise Ausführlichkeit. Aus dem gleichen Grund wie dem, was wir zuvor gesehen haben (nämlich der logischen Reihenfolge der Operationen), können wir nicht einfach nach etwas gruppieren, das wir projizieren.
Dies ist ungültiges SQL:
SELECT first_name || ' ' || last_name AS name
FROM customer
GROUP BY name
Dies ist gültig (Wiederholung des Ausdrucks)
SELECT first_name || ' ' || last_name AS name
FROM customer
GROUP BY first_name || ' ' || last_name
Dies gilt auch (Verschachtelung des Ausdrucks)
SELECT name
FROM (
SELECT first_name || ' ' || last_name AS name
FROM customer
) c
GROUP BY name
Ich habe in einem Blog-Beitrag ausführlicher über dieses Thema geschrieben