Frage

Ich lernte etwas einfaches über SQL den anderen Tag:

SELECT c FROM myTbl GROUP BY C

Hat das gleiche Ergebnis wie:

SELECT DISTINCT C FROM myTbl

Was ich bin neugierig ist, ist es irgendetwas anderes in der Art einer SQL-engine verarbeitet den Befehl, oder sind Sie wirklich das gleiche?

Persönlich bevorzuge ich die distinct-syntax, aber ich bin sicher, es ist mehr aus Gewohnheit als alles andere.

EDIT:Dies ist nicht eine Frage, über die Aggregate.Die Verwendung von GROUP BY mit Aggregatfunktionen verstanden wird.

War es hilfreich?

Lösung

MusiGenesis response‘ist funktionell die richtige im Hinblick auf Ihre Frage, wie angegeben; der SQL Server ist intelligent genug, um zu erkennen, dass, wenn Sie „Group By“ verwenden und keine Aggregatfunktionen verwenden, dann, was meinen Sie eigentlich ist „Distinct“ - und daher erzeugt es eine Planausführung, als ob Sie einfach „Distinct verwendet würden ".

Aber ich denke, es ist wichtig zu beachten, Hank 's Antwort als gut - Kavalier Behandlung von ‚Group By‘ und ‚Distinct‘ zu einigen verderblichen gotchas auf der ganzen Linie führen könnte, wenn man nicht aufpasst. Es ist nicht ganz richtig zu sagen, dass dies „keine Frage über Aggregate“, weil Sie über den funktionalen Unterschied zwischen zwei SQL-Abfrage Schlüsselwort zu fragen, von denen ist dafür gedacht, mit Aggregaten verwendet werden sollte und einer von denen nicht.

Ein Hammer kann manchmal in einer Schraube fahren arbeiten, aber wenn man einen Schraubenzieher handlich hat, warum die Mühe machen?

(für die Zwecke dieser Analogie Hammer : Screwdriver :: GroupBy : Distinct und screw => get list of unique values in a table column)

Andere Tipps

GROUP BY können Sie Aggregatfunktionen verwenden, wie AVG, MAX, MIN, SUM und COUNT. Auf der anderen Seite DISTINCT entfernt nur Duplikate.

Zum Beispiel, wenn Sie eine Reihe von Kaufdatensätzen haben, und Sie wollen wissen, wie viel von jeder Abteilung ausgegeben wurde, könnte man so etwas tun:

SELECT department, SUM(amount) FROM purchases GROUP BY department

Dies gibt Ihnen eine Zeile pro Abteilung, die Abteilungsnamen und die Summe aller der amount Werte in allen Zeilen für diese Abteilung enthält.

Es gibt keinen Unterschied (in SQL Server, mindestens).Beide Abfragen verwenden den gleichen Ausführungsplan.

http://sqlmag.com/database-performance-tuning/distinct-vs-group

Vielleicht gibt es ist einen Unterschied, wenn es sub-Abfragen beteiligt:

http://blog.sqlauthority.com/2007/03/29/sql-server-difference-between-distinct-and-group-by-distinct-vs-group-by/

Es gibt keinen Unterschied (Oracle-Stil):

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:32961403234212

Verwenden DISTINCT wenn Sie nur wollen, um Duplikate zu entfernen. Verwenden Sie GROUPY BY wenn Sie Aggregat Operatoren anwenden möchten (MAX, SUM, GROUP_CONCAT, ..., oder eine HAVING-Klausel).

Was ist der Unterschied von einer bloßen Entfernung von Dubletten Funktionalität Sicht

Neben der Tatsache, dass im Gegensatz zu DISTINCT, GROUP BY zum Aggregieren Datum erlaubt pro Gruppe (was von vielen anderen Antworten erwähnt wurde), der wichtigste Unterschied meiner Meinung nach ist die Tatsache, dass die beiden Operationen „passieren“ bei zwei sehr unterschiedlichen Schritten in dem logische Reihenfolge der Operationen, die in einer SELECT Anweisung ausgeführt werden.

Hier sind die wichtigsten Operationen:

  • FROM (einschließlich JOIN, APPLY usw.)
  • WHERE
  • GROUP BY (können Duplikate entfernen)
  • Aggregationen
  • HAVING
  • Fensterfunktionen
  • SELECT
  • DISTINCT (können 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 getan werden kann und wie sie beeinflusst nachfolgende Operationen. Insbesondere die Tatsache, dass der GROUP BY Betrieb "geschieht vor" der SELECT Betrieb (der Vorsprung) bedeutet, dass:

  1. Es hängt nicht von dem Vorsprung (was ein Vorteil sein kann)
  2. Es kann keinen Wert aus der Projektion verwenden (was ein Nachteil sein kann)

1. Es ist nicht von der Projektion abhängig

Ein Beispiel, wo nicht auf dem Vorsprung abhängig ist nützlich, wenn Sie Fensterfunktionen auf verschiedenen Werten berechnet werden sollen:

SELECT rating, row_number() OVER (ORDER BY rating) AS rn
FROM film
GROUP BY rating

Wenn er ausgeführt wird gegen die Sakila Datenbank , ergibt dies:

rating   rn
-----------
G        1
NC-17    2
PG       3
PG-13    4
R        5

Das gleiche könnte nicht mit DISTINCT leicht erreicht 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 ist nicht das, was wir wollten. Die DISTINCT Betrieb „geschieht nach dem“ die Projektion, so können wir nicht mehr DISTINCT Bewertungen entfernen, weil die Fensterfunktion bereits berechnet und projiziert. Um DISTINCT zu verwenden, würden sie auf Nest haben, dass ein Teil der Abfrage:

SELECT rating, row_number() OVER (ORDER BY rating) AS rn
FROM (
  SELECT DISTINCT rating FROM film
) f

Side-Hinweis: In diesem speziellen Fall, könnten wir auch DENSE_RANK() verwenden

SELECT DISTINCT rating, dense_rank() OVER (ORDER BY rating) AS rn
FROM film

2. Es kann keinen Wert aus der Projektion verwenden

Eine der Nachteile SQL ist seine Ausführlichkeit zu Zeiten. Aus dem gleichen Grund wie das, was wir vor (nämlich die logische Reihenfolge der Operationen) gesehen haben, können wir nicht „leicht“ Gruppe von etwas projizieren wir.

Dies ist ungültig SQL:

SELECT first_name || ' ' || last_name AS name
FROM customer
GROUP BY name

Dies gilt (Wiederholung des Ausdrucks)

SELECT first_name || ' ' || last_name AS name
FROM customer
GROUP BY first_name || ' ' || last_name

Dies gilt auch (Verschachtelung den Ausdruck)

SELECT name
FROM (
  SELECT first_name || ' ' || last_name AS name
  FROM customer
) c
GROUP BY name

ich habe in einem Blog-Post zu diesem Thema mehr in der Tiefe geschrieben

Ich erwarte, dass es die Möglichkeit für subtile Unterschiede in der Ausführung ist. Ich überprüfte die Ausführungspläne für zwei funktional äquivalente Abfragen entlang dieser Linien in Oracle 10g:

core> select sta from zip group by sta;

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    58 |   174 |    44  (19)| 00:00:01 |
|   1 |  HASH GROUP BY     |      |    58 |   174 |    44  (19)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| ZIP  | 42303 |   123K|    38   (6)| 00:00:01 |
---------------------------------------------------------------------------

core> select distinct sta from zip;

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    58 |   174 |    44  (19)| 00:00:01 |
|   1 |  HASH UNIQUE       |      |    58 |   174 |    44  (19)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| ZIP  | 42303 |   123K|    38   (6)| 00:00:01 |
---------------------------------------------------------------------------

Der mittlere Betrieb ist etwas anders: „HASH GROUP BY“ vs. „HASH UNIQUE“, aber die geschätzten Kosten usw. sind identisch. Ich ausgeführt diese dann mit Verfolgung auf und die tatsächliche Betrieb zählt waren für beide gleich (außer dass die zweiten keine körperlichen zu tun haben liest wegen Caching).

Aber ich glaube, dass, weil die Operationsnamen unterschiedlich sind, würde die Ausführung etwas andere Codepfade folgen und eröffnet die Möglichkeit, mehr signifikanten Unterschiede.

Ich denke, Sie sollten die DISTINCT Syntax für diesen Zweck bevorzugen. Es ist nicht nur Gewohnheit, es zeigt deutlich den Zweck der Abfrage.

Für die Abfrage Sie auf dem Laufenden, sie sind identisch. Aber für andere Anfragen, die nicht wahr sein können.

Zum Beispiel, es ist nicht das gleiche wie:

SELECT C FROM myTbl GROUP BY C, D

ich alle oben genannten Kommentare lesen, aber nicht sehen, jemand auf den Hauptunterschied zwischen Gruppierung und Distinct abgesehen von der Aggregation Bit hingewiesen.

Distinct Gibt alle Zeilen dann de-dupliziert sie während Gruppierung de-Deduplizierung die Zeilen, wie sie durch den Algorithmus einer nach dem anderen lesen sind.

Das heißt, sie zu unterschiedlichen Ergebnissen führen können!

Zum Beispiel erzeugen die folgenden Codes unterschiedliche Ergebnisse:

SELECT distinct ROW_NUMBER() OVER (ORDER BY Name), Name FROM NamesTable

 SELECT ROW_NUMBER() OVER (ORDER BY Name), Name FROM NamesTable
GROUP BY Name

Wenn es 10 Namen in der Tabelle sind, wo 1 davon ein Duplikat einer anderen dann die erste Abfrage gibt 10 Reihen, während die zweite Abfrage 9 Zeilen zurückgibt.

Der Grund ist das, was ich oben gesagt, so dass sie sich anders verhalten!

Wenn Sie DISTINCT verwenden mit mehreren Spalten wird die Ergebnismenge nicht gruppiert werden, wie es wird mit GROUP BY, und Sie können Aggregatfunktionen nicht mit DISTINCT verwenden.

Sie haben unterschiedliche Semantik, auch wenn sie gleichwertige Ergebnisse auf bestimmte Daten haben, geschehen.

GROUP BY hat eine sehr spezifische Bedeutung, die distinct (heh) von der DISTINCT-Funktion ist.

GROUP BY die Abfrageergebnisse bewirkt, dass der gewählte Ausdruck gruppiert werden, können Aggregatfunktionen dann angewendet werden, und diese auf jeder Gruppe handeln, anstatt die gesamte resultset.

Hier ist ein Beispiel, die helfen können:

eine Tabelle, die wie folgt aussieht:

name
------
barry
dave
bill
dave
dave
barry
john

Diese Abfrage:

SELECT name, count(*) AS count FROM table GROUP BY name;

Wird Ausgabe wie folgt erzeugen:

name    count
-------------
barry   2
dave    3
bill    1
john    1

Was ist offensichtlich ganz anders mit DISTINCT. Wenn Sie Ihre Ergebnisse gruppieren möchten, GROUP BY verwenden, wenn Sie nur eine eindeutige Liste von einer bestimmten Spalte möchten, verwenden Sie DISTINCT. Dadurch erhalten Sie Ihre Datenbank eine Chance, die Abfrage für Ihre Bedürfnisse zu optimieren.

Bitte verwenden Sie keine GROUP BY, wenn Sie DISTINCT bedeuten, auch wenn sie die gleiche Arbeit geschehen. Ich gehe davon aus Sie versuchen Millisekunden von Abfragen zu rasieren, und ich muss darauf hinweisen, dass Entwickler Zeit ist um Größenordnungen teurer als Computerzeit.

Wenn Sie eine GROUP BY ohne Aggregatfunktion verwenden, dann intern wird es als DISTINCT behandelt, so dass in diesem Fall gibt es keinen Unterschied zwischen GROUP BY und DISTINCT.

Aber wenn man mit DISTINCT-Klausel versehen ist besser, um es für Ihre einzigartige Datensätze zu finden, weil das Ziel der GROUP BY ist die Aggregation zu erreichen.

Gruppe wird in Aggregat Operationen verwendet - wie wenn Sie möchten, eine Anzahl von Bs zu erhalten, indem Spalte C aufgeschlüsselt

select C, count(B) from myTbl group by C

unterscheidet, was es klingt -. Sie eindeutige Zeilen bekommen

In SQL Server 2005, sieht es aus wie der Abfrageoptimierer ist in der Lage, den Unterschied in den simplen Beispielen zu optimieren weg lief ich. Weiß nicht, ob Sie auf, dass in allen Situationen verlassen können, though.

In dieser speziellen Abfrage gibt es keinen Unterschied. Aber natürlich, wenn Sie die Aggregat-Spalten hinzufügen, dann werden Sie haben Gruppe zu verwenden, indem.

Von einer "SQL die Sprache Sicht die beiden Konstrukte sind gleichwertig und die man Sie wählen, ist eine jener‚Lifestyle‘Auswahl haben wir alle zu machen. Ich denke, dass es ein gutes Argument für DISTINCT Wesen deutlicher ist (und daher ist mehr Rücksicht auf die Person, die Ihr Code usw. erben werden), aber das bedeutet nicht, die GROUP BY-Konstrukt ist eine ungültige Wahl.

Ich denke, das ‚GROUP BY für Aggregate ist‘ die falsche Betonung liegt. Folk sollten sich bewusst sein, dass die eingestellte Funktion (MAX, MIN, COUNT, etc.) weggelassen werden, so dass sie die Coder Absicht verstehen kann, wenn es ist.

Die idealen Optimierer entsprechende SQL-Konstrukte erkennen und den idealen Plan entsprechend immer holen. Für Ihr Leben SQL-Engine der Wahl, müssen Sie testen:)

PS beachten Sie die Position des DISTINCT-Schlüsselwort in der select-Klausel kann zu unterschiedlichen Ergebnissen führen z.B. Kontrast:

SELECT COUNT(DISTINCT C) FROM myTbl;

SELECT DISTINCT COUNT(C) FROM myTbl;

In Teradata Perspektive :

Von einer Ergebnismenge Sicht spielt es keine Rolle, ob Sie DISTINCT oder GROUP BY in Teradata verwenden. Das Antwort-Set wird das gleiche sein.

Aus Performance-Sicht, es ist nicht das gleiche.

Um zu verstehen, welche Auswirkungen Leistung, müssen Sie wissen, was auf Teradata passiert, wenn eine Erklärung mit DISTINCT oder GROUP BY ausgeführt wird.

Im Fall von DISTINCT werden die Zeilen verteilt sofort ohne Voraggregation stattfindet, während im Fall von GROUP BY, in einem ersten Schritt ein Voraggregation getan wird und nur dann wird die eindeutigen Werte für die AMPs neu verteilt.

Denken Sie nicht jetzt, dass GROUP BY ist immer besser, von einer Performance-Sicht. Wenn Sie viele verschiedene Werte haben, ist der Voraggregation Schritt der GROUP BY nicht sehr effizient. Teradata hat die Daten zu sortieren Duplikate zu entfernen. In diesem Fall kann es zunächst auf die Umverteilung besser sein, das heißt die DISTINCT-Anweisung verwenden. Nur wenn es viele doppelte Werte sind, ist die GROUP BY-Anweisung wahrscheinlich die bessere Wahl, da nur ein einziges Mal die Deduplizierung Schritt erfolgt nach Neuverteilung.

Kurz gesagt, DISTINCT vs. GROUP BY in Teradata bedeutet:

GROUP BY -> für viele Duplikate DISTINCT -> keine oder wenige Duplikate nur. Manchmal bei der Verwendung von DISTINCT, Sie laufen auf einem AMP aus Spool-Raum. Der Grund dafür ist, dass Umverteilung stattfindet, sofort und Schrägstellung könnte dazu führen, AMPs aus dem Raum zu laufen.

Wenn dies geschieht, haben Sie wahrscheinlich eine bessere Chance, mit GROUP BY, als Duplikate bereits in einem ersten Schritt entfernt werden, und weniger Daten über die AMPs bewegten.

Sie bemerken nur, weil Sie eine einzelne Spalte auswählen.

Versuchen Sie, zwei Felder auswählen und sehen, was passiert.

Gruppierung sollte wie folgt verwendet werden:

SELECT name, SUM(transaction) FROM myTbl GROUP BY name

, die die Summe aller Transaktionen für jede Person zeigen würde.

Ich weiß, es ist eine alte Post. Aber es kommt vor, dass ich eine Abfrage hatte die Gruppe von nur verwendet unterschiedlichen Werten zurück, wenn die Abfrage in Kröte mit und Oracle Report alles funktionierte gut, ich meine, eine gute Reaktionszeit. Wenn wir von Oracle 9i migriert in Toad die Reaktionszeit bis 11g ausgezeichnet war aber in den reporten ca. 35 Minuten dauerte es, den Bericht zu beenden, wenn frühere Version verwendet es dauerte etwa 5 Minuten.

Die Lösung wurde durch die Gruppe zu ändern und verwenden DISTINCT und jetzt der Bericht ausgeführt wird etwa 30 Sekunden in.

Ich hoffe, dies für jemanden mit der gleichen Situation nützlich ist.

So wie ich es immer verstanden, dass unterschiedliche Verwendung derselben von jedem Feld als Gruppierung ist, dass Sie in der Reihenfolge, die Sie ausgewählt.

heißt:

select distinct a, b, c from table;

ist die gleiche wie:

select a, b, c from table group by a, b, c

Funtional Effizienz ist völlig anders. Wenn Sie möchten, dass nur „Rückgabewert“ außer für Duplizierungen, einen auszuwählen, verwenden Sie unterschiedliche besser ist als Gruppe durch. Denn "Gruppe von" umfasst (Sortierung + Entfernen), "distinct" umfasst (Entfernen)

In Hive (HQL), Gruppe kann als verschiedene Art und Weise schneller sein, da erstere erfordert nicht alle Felder in der Tabelle zu vergleichen. Siehe https://sqlperformance.com/2017 / 01 / t-sQL-Abfragen / Überraschungen-Annahmen-group-by-eindeutige .

Es gibt keinen signifikant Unterschied zwischen Gruppe und unterschiedliche Klausel außer der Verwendung von Aggregatfunktionen. Beide können verwendet werden, um die Werte zu unterscheiden, aber wenn in Sicht der Performance-Gruppe durch ist besser. Wenn unterschiedliches Schlüsselwort verwendet wird, intern verwendet, es ist eine Art Operation, die Ansicht in Ausführungsplan sein kann.

Versuchen einfaches Beispiel

@tmpresult Tabelle Deklarieren (   Id Tinyint )

Einfügen in @tmpresult wählen Sie 5 Union alle wählen Sie 2 Union alle wählen Sie 3 Union alle Wählen Sie 4

Wählen Sie verschiedene Ich würde Von @tmpresult

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top