Datensätze mit maximalem Wert für jede Gruppe gruppierter SQL-Ergebnisse abrufen
Wie kommst du auf die Zeilen der max-Wert für jede Gruppierung?
Ich habe gesehen, einige übermäßig komplizierte Varianten auf diese Frage, und keines mit einer guten Antwort. Ich habe versucht zusammen zu stellen die einfachste mögliche Beispiel:
Gegeben eine Tabelle wie unten, mit dem person, Gruppe, Alter und Spalten, wie würden Sie die älteste person in jeder Gruppe? (Ein Band innerhalb einer Gruppe sollten die ersten alphabetischer Folge)
Person | Group | Age
---
Bob | 1 | 32
Jill | 1 | 34
Shawn| 1 | 42
Jake | 2 | 29
Paul | 2 | 36
Laura| 2 | 39
Gewünschte Ergebnis einstellen:
Shawn | 1 | 42
Laura | 2 | 39
InformationsquelleAutor der Frage Yarin | 2012-08-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es eine super-einfache Möglichkeit, dies zu tun in mysql:
Dies funktioniert, da in mysql darfst du dich nicht aggregierte nicht-group-Spalten, in dem Fall mysql nur die Renditen der ersten Zeile. Die Lösung ist die erste, um die Daten so, dass für jede Gruppe die Zeile, die Sie wollen, ist die erste, dann die Gruppe von Spalten, die Sie möchten, dass der Wert für.
Vermeiden Sie komplizierte Unterabfragen, die versuchen zu finden, die
max()
etc, und auch die Probleme, die die Rückkehr mehrere Zeilen, wenn es mehr als eine mit der gleichen maximalen Wert (wie die anderen Antworten tun würde)Hinweis: Dies ist ein mysql-nur Lösung. Alle anderen Datenbanken, die ich kenne, werfen Sie einen SQL-syntax-Fehler mit der Meldung "nicht aggregierte Spalten sind nicht in der group by-Klausel" oder so ähnlich. Da diese Lösung verwendet undokumentierte Verhalten, die vorsichtiger aufnehmen wollen, ein test, um zu behaupten, dass es bleibt arbeiten sollte eine zukünftige version von MySQL, dieses Verhalten zu ändern.
Version 5.7 aktualisiert:
Seit der version 5.7, die
sql-Modus
Einstellung enthältONLY_FULL_GROUP_BY
standardmäßig, so diese Arbeit zu machen müssen Sie nicht haben diese option ("Bearbeiten" die option Datei für den server so entfernen Sie diese Einstellung).InformationsquelleAutor der Antwort Bohemian
Die richtige Lösung ist:
Wie es funktioniert:
Es stimmt jede Zeile von
o
mit allen Zeilen ausb
mit dem gleichen Wert in der SpalteGroup
und einen größeren Wert in der SpalteAge
. Jede Zeile vono
nicht mit dem maximalen Wert seiner Gruppe in SpalteAge
wird entsprechend eine oder mehrere Zeilen ausb
.Den
LEFT JOIN
macht es die älteste person in der Gruppe (einschließlich der Personen, die alleine in Ihrer Gruppe) mit einer Zeile vollerNULL
s ausb
('keine größte Alter in der Gruppe").Mit
INNER JOIN
lässt diese Reihen, die nicht zusammenpassen und Sie werden ignoriert.Den
WHERE
Klausel hält nur die Zeilen mitNULL
s in den Felder extrahiert ausb
. Sie sind die ältesten Personen aus jeder Gruppe.Weitere Lesungen
Diese Lösung und viele andere sind erklärt in dem Buch SQL-Antipatterns: Vermeidung der Gefahren von Datenbank-Programmierung
InformationsquelleAutor der Antwort axiac
Meine einfache Lösung für SQLite (und wahrscheinlich MySQL):
Aber es funktioniert nicht in einer PostgreSQL und vielleicht einige andere Plattformen.
In PostgreSQL können Sie UNTERSCHIEDLICHE AUF Klausel:
InformationsquelleAutor der Antwort Igor Kulagin
Dem man beitreten kann gegen eine Unterabfrage, zieht die
MAX(Group)
undAge
. Diese Methode ist tragbar in den meisten RDBMS.InformationsquelleAutor der Antwort Michael Berkowski
Mithilfe von ranking-Methode.
InformationsquelleAutor der Antwort sel
axiac die Lösung ist, was funktioniert am besten für mich am Ende. Ich hatte eine zusätzliche Komplexität jedoch: ein berechnetes "max-Wert", abgeleitet von zwei Spalten.
Verwenden wir das gleiche Beispiel: ich möchte die älteste person in jeder Gruppe. Wenn es Menschen gibt, die sind gleich alt, nehmen die höchste person.
Ich musste das left join zwei mal zu bekommen ist dieses Verhalten:
Hoffe, das hilft! Ich denke, es sollte eine bessere Möglichkeit, dies zu tun, obwohl...
InformationsquelleAutor der Antwort Arthur C
Allgemeine Tabellenausdrücke Verwenden - Common Table Expressions:
InformationsquelleAutor der Antwort Marvin
Meine Lösung funktioniert nur, wenn Sie müssen abrufen, die nur eine Spalte, aber für meine Bedürfnisse war die beste Gefundene Lösung im Hinblick auf performance (nutze es nur eine einzige Abfrage!):
Es mit GROUP_CONCAT, um eine geordnete concat Liste und dann habe ich substring nur das erste.
InformationsquelleAutor der Antwort Antonio Giovanazzi
Können Sie auch versuchen,
InformationsquelleAutor der Antwort Ritwik
Diese Methode hat den Vorteil, dass Sie die Rangfolge nach einer anderen Spalte, und nicht wegwerfen, die anderen Daten. Es ist sehr nützlich in einer situation, wo Sie versuchen, die Liste der Bestellungen mit einer Spalte für Elemente, die Auflistung der schwersten zuerst.
Quelle: http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat
InformationsquelleAutor der Antwort Ray Foss
Nicht sicher, ob MySQL hat row_number-Funktion. Wenn ja, können Sie es verwenden, um das gewünschte Ergebnis zu erhalten. Auf SQL Server, die Sie tun können, etwas ähnliches wie:
InformationsquelleAutor der Antwort user130268
lassen Sie den Tabellennamen, werden die Menschen
InformationsquelleAutor der Antwort user3475425
Wenn ID(und alle coulmns) benötigt, die von mytable
InformationsquelleAutor der Antwort mayank kumar
Dies ist, wie ich immer bin N max Zeilen pro Gruppe in mysql
wie es funktioniert:
co.country = ci.country
) < 1
so für 3 Elemente ) < 3co.id < ci.id
Vollständiges Beispiel hier:
mysql select n max-Werte pro Gruppe
InformationsquelleAutor der Antwort Vanko
Habe ich eine einfache Lösung mit
WHERE IN
InformationsquelleAutor der Antwort Khalid Musa Sagar
InformationsquelleAutor der Antwort Harshad C
Würde ich nicht verwenden-Gruppe als Spalte namens, da es reserviertes Wort ist. Jedoch mit SQL funktionieren würde.
InformationsquelleAutor der Antwort Bae Cheol Shin