Sind diese beiden Abfragen gleich - GROUP BY vs. DISTINCT?

7

Diese beiden Abfragen scheinen die gleichen Ergebnisse zu liefern. Ist das Zufall oder sind sie wirklich gleich?

1.

%Vor%

2.

%Vor%

Ein bisschen Erklärung: Ich versuche eine eindeutige Liste von Artikeln aus einer Tabelle voller Transaktionen zu erhalten. Für jedes Element suche ich nach der ItemNumber (das identifizierende Feld) und der neuesten ItemDescription.

    
MCS 28.07.2010, 15:11
quelle

8 Antworten

5

Ihr Beispiel # 2 ließ mich für eine Weile am Kopf kratzen - ich dachte mir: "Sie können nicht DISTINCT eine einzelne Spalte, was würde das bedeuten?" - bis ich realisierte, was vor sich geht.

Wenn Sie

haben %Vor%

Sie sind nicht , obwohl sie scheinbar nach bestimmten Werten von t.ItemNumber gefragt haben! Ihr Beispiel # 2 wird tatsächlich wie

geparst %Vor%

mit syntaktisch korrekten, aber überflüssigen Klammern um t.ItemNumber . Es gilt für das Ergebnis als Ganzes, dass DISTINCT gilt.

In diesem Fall erhalten Sie die gleichen Ergebnisse, da Ihre Gruppe GROUP BY nach der Spalte gruppiert, die tatsächlich variiert. Ich bin eigentlich etwas überrascht, dass SQL Server nicht (im GROUP BY -Beispiel) darauf besteht, dass die Spalte mit der subquered-Angabe in der GROUP BY -Liste erwähnt wird.

    
AakashM 28.07.2010, 15:31
quelle
4

Die gleichen Ergebnisse, aber die zweite scheint einen teureren Sortierschritt zu haben, um die DISTINCT auf meinen schnellen Test anzuwenden.

Beide wurden jedoch von ROW_NUMBER außer Sichtweite geschlagen ...

%Vor%

edit ... was wiederum von Joe's Lösung zu meinem Testaufbau.

Pläne http://img842.imageshack.us/img842/4105/executionplan.png

Testeinrichtung

%Vor%     
Martin Smith 28.07.2010 15:42
quelle
3

Basierend auf den Daten & amp; einfache Abfragen, beide werden die gleichen Ergebnisse zurückgeben. Die grundlegenden Operationen sind jedoch sehr unterschiedlich.

DISTINCT , wie AakashM mich aufzeigen kann, wird auf alle Spaltenwerte angewendet, einschließlich solcher aus Subselects und berechneten Spalten. Alle DISTINCT does entfernen Duplikate basierend auf allen betroffenen Spalten aus der Sichtbarkeit . Aus diesem Grund wird es allgemein als Hack betrachtet, weil die Leute es verwenden werden, um Duplikate loszuwerden, ohne zu verstehen, warum die Abfrage sie überhaupt zurückgibt (weil sie in der Regel IN oder EXISTS anstelle einer Verknüpfung verwenden sollten) ). PostgreSQL ist die einzige Datenbank, die ich kenne, mit einer DISTINCT ON -Klausel, die genauso funktioniert wie das OP wahrscheinlich.

Eine GROUP BY -Klausel ist anders - sie wird hauptsächlich zum Gruppieren für die genaue Verwendung von Aggregatfunktionen verwendet. Um diese Funktion zu betreiben, sind Spaltenwerte eindeutige Werte basierend auf den in der GROUP BY-Klausel definierten Werten. Diese Abfrage würde DISTINCT niemals benötigen, da die interessierenden Werte bereits eindeutig sind.

Fazit

Dies ist ein schlechtes Beispiel, da DISTINCT und GROUP BY als gleich dargestellt werden, wenn sie nicht gleich sind.

    
OMG Ponies 28.07.2010 16:29
quelle
3

Wenn Sie mindestens 2005 laufen und ein CTE verwenden können, ist dies ein kleiner Reiniger IMHO.

EDIT: Wie in Martins Antwort , das geht auch viel besser.

%Vor%     
Joe Stefanelli 28.07.2010 15:25
quelle
2

Ja, sie werden die gleichen Ergebnisse liefern.

    
Mike M. 28.07.2010 15:14
quelle
2

Da Sie keine Aggregatfunktionen verwenden, sollte SQL Server intelligent genug sein, um GROUP BY als DISTINCT zu behandeln.

Vielleicht möchten Sie auch den folgenden Stack Overflow-Beitrag lesen, um mehr zu diesem Thema zu lesen:

Daniel Vassallo 28.07.2010 15:15
quelle
1

GROUP BY wird benötigt, um Ergebnisse korrekt zurückzugeben, wenn Aggregatfunktionen in einer SQL-Abfrage verwendet werden. Da Sie keine Aggregatfunktion verwenden, ist% ce_de% nicht erforderlich, und die Abfragen sind daher identisch.

    
pkananen 28.07.2010 15:17
quelle
1

Ja, sie geben die gleichen Ergebnisse zurück.

Normalerweise gruppiert die Gruppenklausel ( hier ) die Zeilen nach der angegebenen Spalte eine Summe in Ihrer Select-Anweisung. Also wenn du einen Tisch wie:

hast %Vor%

Wenn Sie nach Kunden gruppieren und nach der Summe oder dem Bestellpreis fragen, erhalten Sie

%Vor%

Im Gegensatz dazu macht das distinct (gefunden hier ) es so, dass Sie keine doppelten Zeilen haben. In diesem Fall bleibt die ursprüngliche Tabelle gleich, da sich jede Zeile von den anderen unterscheidet.

    
Kyra 28.07.2010 15:20
quelle