Ein weiterer Ansatz ist die Verwendung von MySQL Benutzervariablen, um einen „Gruppenwechsel zu identifizieren "in den group
Werten.
Wenn Sie mit einer extra Spalte zurückgegeben leben können, so etwas wie dies funktioniert:
SELECT IF(s.group = @prev_group,0,1) AS latest_in_group
, s.id
, @prev_group := s.group AS `group`
, s.date
, s.title
FROM (SELECT t.id,t.group,t.date,t.title
FROM titles t
ORDER BY t.group DESC, t.date DESC, t.id DESC
) s
JOIN (SELECT @prev_group := NULL) p
HAVING latest_in_group = 1
ORDER BY s.group DESC
Was dies tut, alle Zeilen von group
wird die Bestellung und durch date
in absteigender Reihenfolge. (Wir geben DESC für alle Spalten in ORDER BY an, falls es einen Index für (group,date,id)
gibt, den MySQL "reverse scan" ausführen kann. Die Einfügung der Spalte id
führt uns zu einem deterministischen (wiederholbaren) Verhalten, in dem Fall Es gibt mehr als eine Zeile mit dem letzten date
Wert.) Das ist die Inline-Ansicht aliased als s
.
Der "Trick", den wir verwenden, besteht darin, den group
Wert mit dem group
Wert aus der vorherigen Zeile zu vergleichen. Wann immer wir einen anderen Wert haben, wissen wir, dass wir eine "neue" Gruppe beginnen und dass diese Zeile die "letzte" Zeile ist (wir haben die IF-Funktion, die eine 1 zurückgibt). Ansonsten (wenn die Gruppenwerte übereinstimmen), ist es nicht die letzte Zeile (und die IF-Funktion gibt eine 0 zurück).
Dann filtern wir alle Zeilen, die nicht latest_in_group
als 1 gesetzt haben.
Es ist möglich, dass zusätzliche Spalt zu entfernen, indem die Abfrage (als Inline-Ansicht) in einer anderen Abfrage Verpackung:
SELECT r.id
, r.group
, r.date
, r.title
FROM (SELECT IF(s.group = @prev_group,0,1) AS latest_in_group
, s.id
, @prev_group := s.group AS `group`
, s.date
, s.title
FROM (SELECT t.id,t.group,t.date,t.title
FROM titles t
ORDER BY t.group DESC, t.date DESC, t.id DESC
) s
JOIN (SELECT @prev_group := NULL) p
HAVING latest_in_group = 1
) r
ORDER BY r.group DESC
Wenn Sie nur die beiden Spalten benötigen (z. B. ID und den letzten Zeitstempel), könnte dies funktionieren: http://stackoverflow.com/a/4448536/722036. Es ist ** schneller ** als die Verwendung von Unterabfragen in einer riesigen Tabelle mit Millionen von Zeilen. –