ID FirstName LastName
1 John Doe
2 Bugs Bunny
3 John Johnson
Ich möchte DISTINCT
Ergebnisse aus der FirstName
Spalte auswählen , benötige aber das entsprechende ID
und LastName
.
Die Ergebnismenge muss nur eine anzeigen John
, jedoch eine ID
von 1 und eine LastName
von Doe.
DISTINCT
ist keine Funktion. Alle Antworten mitDISTINCT()
sind falsch. Der Fehler wird angezeigt, wenn Sie ihn nicht danach platzierenSELECT
.ALL
Antworten in Klammern nach dem Wort "eindeutig" sind in der Tat falsch. Distinct ist KEINE Funktion und kann daher keinen Parameter akzeptieren. Die folgenden Klammern werden einfach ignoriert. Es sei denn, Sie verwenden PostgreSQL, bei dem die Klammern einen "komplexen Datentyp" bildenAntworten:
Versuchen Sie diese Abfrage
quelle
5.7.5+
für die geänderteGROUP BY
BehandlungDas
DISTINCT
Schlüsselwort funktioniert nicht so, wie Sie es erwarten. Wenn Sie verwendenSELECT DISTINCT col1, col2, col3
, wählen Sie tatsächlich alle eindeutigen {col1, col2, col3} Tupel aus.quelle
Um zu vermeiden , potenziell Ergebnisse unerwartet bei Verwendung
GROUP BY
ohne Aggregatfunktion, wie sie in der akzeptierte Antwort verwendet wird , weil MySQL ist kostenlos abrufen ANY Wert innerhalb des Datensatzes gruppiert werden , wenn nicht eine Aggregatfunktion mit [sic] und Probleme mitONLY_FULL_GROUP_BY
. Bitte erwägen Sie die Verwendung eines Ausschluss-Joins.Ausschluss beitreten - Eindeutige Entitäten
Angenommen, der Vor- und Nachname sind eindeutig indiziert (eindeutig) , besteht eine Alternative dazu
GROUP BY
darin,LEFT JOIN
die Ergebnismenge mit a zu filtern, was auch als Ausschluss-JOIN bezeichnet wird.Siehe Demonstration
Aufsteigende Reihenfolge (AZ)
Abrufen des nach Nachnamen geordneten eindeutigen Vornamens von AZ
Abfrage
Ergebnis
Absteigende Reihenfolge (ZA)
So rufen Sie den nach Nachnamen geordneten eindeutigen Vornamen von ZA ab
Abfrage
Ergebnis
Sie können die resultierenden Daten dann wie gewünscht bestellen.
Ausschluss beitreten - Mehrdeutige Entitäten
Wenn die Kombination aus Vor- und Nachname nicht eindeutig (mehrdeutig) ist und Sie mehrere Zeilen mit denselben Werten haben, können Sie die Ergebnismenge filtern, indem Sie eine ODER-Bedingung in die JOIN-Kriterien aufnehmen, um auch nach ID zu filtern.
Siehe Demonstration
Tabellenname Daten
Abfrage
Ergebnis
Bestellte Unterabfrage
BEARBEITEN
Meine ursprüngliche Antwort unter Verwendung einer geordneten Unterabfrage wurde vor MySQL 5.7.5 geschrieben , was aufgrund der Änderungen mit nicht mehr anwendbar ist
ONLY_FULL_GROUP_BY
. Bitte verwenden Sie stattdessen die obigen Beispiele für Ausschlussverknüpfungen.Es ist auch wichtig zu beachten; wenn
ONLY_FULL_GROUP_BY
deaktiviert ist (ursprüngliche Verhalten vor MySQL 5.7.5) , die Verwendung vonGROUP BY
ohne einer Aggregatfunktion zu unerwarteten Ergebnissen führen, weil MySQL frei zu wählen , ist ANY - Wert innerhalb des Datensatzes gruppiert sind [sic] .Dies bedeutet, dass ein
ID
oderlastname
-Wert abgerufen werden kann , der der abgerufenenfirstname
Zeile nicht zugeordnet ist.WARNUNG
Mit MySQL werden
GROUP BY
bei Verwendung mit MySQL möglicherweise nicht die erwarteten Ergebnisse erzieltORDER BY
Siehe Testfallbeispiel
Die beste Implementierungsmethode, um die erwarteten Ergebnisse sicherzustellen, besteht darin, den Ergebnismengenbereich mithilfe einer geordneten Unterabfrage zu filtern.
Tabellenname Daten
Abfrage
Ergebnis
Vergleich
Demonstration der unerwarteten Ergebnisse bei Verwendung
GROUP BY
in Kombination mitORDER BY
Abfrage
Ergebnis
quelle
Ordering is done after grouping.
, also Nein, nicht in diesem Anwendungsfall. Außerdem ignoriert MariaDB ORDER BY in Unterabfragen (gemäß SQL-Standard) ohne aLIMIT
. Sie würden wollen , eine verwendenWindow Function
Klärung Weitere Sie Ihre Frage im stellen sollten DBA Stack , da dies eine Frage zu MySQL beziehen istGROUP BY
kann einen beliebigen Wert innerhalb des gruppierten Datensatzes auswählen, es sei denn, für diese Spalten wird eine Aggregatfunktion verwendet, um einen bestimmten Wert zu erzwingen. Alsolastname
oderid
kann aus einer der bestellten Zeilen kommen. Das ursprüngliche Unterabfragebeispiel war standardmäßig akzeptabel,MySQL <= 5.7.4
leidet aber technisch immer noch unter dem Problem. DasORDER BY
hilft zwar, eine zufällige Auswahl zu verhindern, ist aber theoretisch immer noch möglich, jedoch mit einer wesentlich geringeren Wahrscheinlichkeit als ohne Verwendung derORDER BY
Unterabfrage.quelle
HAVING
wurde meine Abfrage um 50% langsamer.quelle
Wie wäre es mit
quelle
Sie sind sich nicht sicher, ob Sie dies mit MySQL tun können, aber Sie können einen CTE in T-SQL verwenden
Andernfalls müssen Sie möglicherweise eine temporäre Tabelle verwenden.
quelle
Wie von fyrye hervorgehoben , bezieht sich die akzeptierte Antwort auf ältere Versionen von MySQL, die
ONLY_FULL_GROUP_BY
noch nicht eingeführt wurden. Mit MySQL 8.0.17 (in diesem Beispiel verwendet) wirdONLY_FULL_GROUP_BY
die folgende Fehlermeldung angezeigt, sofern Sie nicht deaktivieren :Eine Möglichkeit, dies zu umgehen , wird von fyrye nicht erwähnt , aber in https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html beschrieben , besteht darin, die
ANY_VALUE()
Funktion auf die Spalten anzuwenden , die sich befinden nicht in derGROUP BY
Klausel (id
undlastName
in diesem Beispiel):Wie in den oben genannten Dokumenten geschrieben,
quelle
ANY_VALUE()
da meine Antworten und Kommentare darauf abzielen, mehrdeutige und unvorhersehbare Ergebnismengen zu verhindern. Wie der Funktionsname schon sagt, kann dies dazu führen, dass ein beliebiger Wert aus den ausgewählten Zeilen abgerufen wird. Ich würde mit vorschlagenMAX
oderMIN
statt.Denken Sie daran, wenn Sie die Gruppe nach und nach dieser Reihenfolge verwenden. MySQL ist die EINZIGE Datenbank, in der Spalten in der Gruppe nach und / oder nach Stück sortiert verwendet werden können, die nicht Teil der select-Anweisung sind.
Beispiel: Wählen Sie Spalte1 aus der Tabellengruppe nach Spalte2 und Reihenfolge nach Spalte3 aus
In anderen Datenbanken wie Postgres, Oracle, MSSQL usw. funktioniert das nicht. In diesen Datenbanken müssten Sie Folgendes tun
Wählen Sie Spalte1, Spalte2, Spalte3 aus der Tabellengruppe nach Spalte2 und Reihenfolge nach Spalte3
Nur einige Informationen für den Fall, dass Sie Ihren aktuellen Code jemals in eine andere Datenbank migrieren oder in einer anderen Datenbank arbeiten und versuchen, Code wiederzuverwenden.
quelle
Sie können group by verwenden, um unterschiedliche Werte und entsprechende Felder anzuzeigen.
Jetzt haben Sie folgende Ausgabe erhalten:
Wenn du gerne antworten möchtest
Verwenden Sie dann diese Abfrage.
quelle
Wäre die beste Wahl IMO
quelle
quelle
DISTINCT()
ist keine Funktion. Auch DISTINCT und GROUP BY machen dasselbe, also ohne Grund beide.