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 mit ONLY_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
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname > t2.lastname
WHERE t2.id IS NULL;
Ergebnis
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |
Absteigende Reihenfolge (ZA)
So rufen Sie den nach Nachnamen geordneten eindeutigen Vornamen von ZA ab
Abfrage
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname < t2.lastname
WHERE t2.id IS NULL;
Ergebnis
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
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
(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson'),
(4, 'John', 'Doe'),
(5, 'John', 'Johnson')
Abfrage
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND (t1.lastname > t2.lastname
OR (t1.firstname = t1.firstname AND t1.lastname = t2.lastname AND t1.id > t2.id))
WHERE t2.id IS NULL;
Ergebnis
| id | firstname | lastname |
|----|-----------|----------|
| 1 | John | Doe |
| 2 | Bugs | Bunny |
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 von GROUP 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
oder lastname
-Wert abgerufen werden kann , der der abgerufenen firstname
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
(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson')
Abfrage
SELECT * FROM (
SELECT * FROM table_name ORDER BY ID DESC
) AS t1
GROUP BY FirstName
Ergebnis
| ID | first | last |
|----|-------|---------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
Vergleich
Demonstration der unerwarteten Ergebnisse bei Verwendung GROUP BY
in Kombination mitORDER BY
Abfrage
SELECT * FROM table_name GROUP BY FirstName ORDER BY ID DESC
Ergebnis
| ID | first | last |
|----|-------|-------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |