Mysql
 sql >> Datenbank >  >> RDS >> Mysql

SQL wählt nur Zeilen mit maximalem Wert in einer Spalte aus

Auf den ersten Blick...

Alles, was Sie brauchen, ist ein GROUP BY -Klausel mit dem MAX Aggregatfunktion:

SELECT id, MAX(rev)
FROM YourTable
GROUP BY id

So einfach ist es nie, oder?

Mir ist gerade aufgefallen, dass Sie den content benötigen Spalte.

Dies ist eine sehr häufige Frage in SQL:Finden Sie die gesamten Daten für die Zeile mit einem maximalen Wert in einer Spalte pro Gruppenkennung. Das habe ich während meiner Karriere oft gehört. Eigentlich war es eine der Fragen, die ich im technischen Vorstellungsgespräch meiner jetzigen Stelle beantwortet habe.

Es ist tatsächlich so üblich, dass die Stack Overflow-Community ein einzelnes Tag erstellt hat, nur um Fragen wie diese zu behandeln: .

Grundsätzlich haben Sie zwei Ansätze, um dieses Problem zu lösen:

Beitritt mit einfacher group-identifier, max-value-in-group Unterabfrage

Bei diesem Ansatz finden Sie zuerst den group-identifier, max-value-in-group (bereits oben gelöst) in einer Unterabfrage. Dann verbinden Sie Ihre Tabelle mit der Unterabfrage mit Gleichheit bei beiden group-identifier und max-value-in-group :

SELECT a.id, a.rev, a.contents
FROM YourTable a
INNER JOIN (
    SELECT id, MAX(rev) rev
    FROM YourTable
    GROUP BY id
) b ON a.id = b.id AND a.rev = b.rev

Links Beitreten mit sich selbst, Anpassen von Beitrittsbedingungen und Filtern

Bei diesem Ansatz verbinden Sie den Tisch mit sich selbst. Gleichheit gehört in den group-identifier . Dann 2 kluge Züge:

  1. Die zweite Join-Bedingung ist, dass der linke Seitenwert kleiner als der rechte Wert ist
  2. Wenn Sie Schritt 1 ausführen, haben die Zeilen, die tatsächlich den maximalen Wert haben, NULL auf der rechten Seite (es ist ein LEFT JOIN , erinnern?). Dann filtern wir das verbundene Ergebnis und zeigen nur die Zeilen an, bei denen die rechte Seite NULL ist .

Am Ende erhalten Sie also:

SELECT a.*
FROM YourTable a
LEFT OUTER JOIN YourTable b
    ON a.id = b.id AND a.rev < b.rev
WHERE b.id IS NULL;

Schlussfolgerung

Beide Ansätze bringen exakt das gleiche Ergebnis.

Wenn Sie zwei Zeilen mit max-value-in-group haben für group-identifier , sind beide Zeilen in beiden Ansätzen im Ergebnis.

Beide Ansätze sind SQL ANSI-kompatibel und funktionieren daher mit Ihrem bevorzugten RDBMS, unabhängig von seiner "Variante".

Beide Ansätze sind auch leistungsfreundlich, Ihre Laufleistung kann jedoch variieren (RDBMS, DB-Struktur, Indizes usw.). Wenn Sie also einen Ansatz dem anderen vorziehen, Benchmark . Und stellen Sie sicher, dass Sie diejenige auswählen, die für Sie am sinnvollsten ist.