Ich habe die folgende MySQL-Abfrage gesehen, die sowohl DISTINCT als auch GROUP BY zusammen verwendet:

SELECT DISTINCT user_id, post_id, post_content FROM some_table GROUP BY post_id, user_id HAVING post_content LIKE "%abc%"; 

Hier ist ein Szenario für die Abfrage: Jeder Benutzer hat eine eindeutige ID, user_id, und kann mehrere Posts erstellen, die durch eine eindeutige ID post_id. Jeder Beitrag würde Text enthalten.

Ich fand dies verwirrend (nachdem ich von Oracle-DBs gekommen war) und hatte folgende Fragen:

  1. Was bedeutet die Verwendung von GROUP BY ohne Aggregation?
  2. Welche Bedeutung hat das Umschalten der Spaltenreihenfolge in SELECT gegenüber GROUP BY ?
  3. Was bedeutet es, die dritte Spalte in GROUP BY wegzulassen?
  4. Warum ist DISTINCT wird zusammen mit GROUP BY verwendet? Wird eine eindeutige Operation ausgeführt, nachdem alle Gruppierungen für das Endergebnis oder zuvor durchgeführt wurden?

Kommentare

  • Punkt 2: Es gibt keine Bedeutung. Das GROUP BY spielt überhaupt keine Rolle (außer dass es in alten Versionen dasselbe ORDER BY impliziert. Das SELECT Reihenfolge ist nur bei der Anordnung der Spalten in der Ausgabe von Bedeutung.

Antwort

ad 1) Alte MySQL-Datenbanken und wenn Sie ONLY_FULL_GROUP_BY deaktivieren, können Sie diese Abfrage durchführen. Wenn alle post_content gleich sind, werden Sie feststellen, dass MySQL einen zufälligen, nicht deterministischen Wert zurückgibt .

ad 2) keine wie auch immer

ad 3) verzögerte Programmierung und es tritt ein Fehler auf, wenn Sie ONLY_FULL_GROUP_BY

ad 4) Nein, es werden alle post_content angezeigt, die mit user_id verbunden sind, post_id, ähnlich wie addind post_content zur Gruppe von

Wie Strawberry bereits sagte, dass diese Abfrage dies nicht tut Sinn machen

Antwort

Die verrückte Fähigkeit, in älteren Versionen von MyS eine teilweise Gruppierung nach zuzulassen QL muss ein Top-Anwärter für die am meisten verursachten Verwirrungen in der IT-Branche sein.

Angesichts der Tabelle:

CREATE TABLE t ( x int not null primary key , y int not null ); INSERT INTO t (x,y) VALUES (1,1),(1,2); 

Die Aussage

SELECT x, y FROM t GROUP BY x 

könnte (1,1) oder (1,2) bedeuten, und MySQL würde zufällig eine davon zurückgeben. DISTINCT spielt in diesem Fall keine Rolle, das Ergebnis ist immer noch unbestimmt.

SQL92 erforderte, dass alle Spalten in der select-Klausel (außer aggregierten Spalten und Konstanten) Teil der GROUP BY-Klausel sind.

SQL99 hat diese Einschränkung etwas gelockert und es uns ermöglicht, Spalten aus der GROUP BY wegzulassen, die funktional von den verbleibenden Spalten abhängig sind. Das heißt,

CREATE TABLE t ( x int not null primary key , y int not null ); SELECT x, y FROM t GROUP by x 

wäre gültig, da y f.d. of x

Überraschenderweise ist (für mich) die spätere Version von MySQL die beste Klasse, wenn es um die Implementierung der SQL99-Version geht. Ich habe es in letzter Zeit nicht überprüft, aber als ich es getan habe, hat MySQL ziemlich komplizierte Szenarien gut behandelt, wobei PostgreSQL nur triviale Szenarien behandelt hat.

Um Ihre Fragen zu beantworten

1)

SELECT x, y FROM t GROUP BY x, y 

bedeutet, dass die Kombination von x, y eine Gruppe ist. In allen möglichen Situationen kann ich mir Folgendes vorstellen:

SELECT DISTINCT x, y FROM t 

Da sie zu unterschiedlichen Zeiten logisch ausgewertet werden, kann es einen Eckfall geben, in dem sie sich tatsächlich unterscheiden (ich kann mir jedoch keinen vorstellen).

2) Keine In dieser Hinsicht handelt es sich um eine Reihe von Spalten, daher gibt es keine Reihenfolge.

3) Siehe oben.

4) Die logische Reihenfolge der Auswertung einer SQL-Abfrage lautet:

FROM, JOIN WHERE GROUP BY HAVING SELECT DISTINCT ORDER BY FETCH FIRST 

Daher sollte GROUP BY vor DISTINCT ausgewertet werden. Ich kann mir keine Situation vorstellen, in der dies von Bedeutung wäre.

In Ihrer Abfrage Ich vermute, dass jemand verwirrende Ergebnisse erzielt und versucht hat, mit DISTINCT ein anderes Ergebnis zu erzielen. Wahrscheinlich hatten sie Glück (oder Pech), das gewünschte Ergebnis zu erzielen erwartet, also blieb der DISTINCT. Der Fehler ist jedoch immer noch vorhanden

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.