Na pierwszy rzut oka...
Wszystko czego potrzebujesz to GROUP BY
klauzula z MAX
funkcja agregująca:
SELECT id, MAX(rev)
FROM YourTable
GROUP BY id
To nigdy nie jest takie proste, prawda?
Właśnie zauważyłem, że potrzebujesz content
kolumna.
To bardzo częste pytanie w SQL:znajdź całe dane dla wiersza z jakąś maksymalną wartością w kolumnie dla pewnego identyfikatora grupy. Wiele słyszałem w swojej karierze. Właściwie było to jedno z pytań, na które odpowiedziałem podczas rozmowy technicznej w mojej obecnej pracy.
W rzeczywistości jest to tak powszechne, że społeczność Stack Overflow utworzyła jeden tag tylko po to, aby radzić sobie z takimi pytaniami:największe-n-na-grupę .
Zasadniczo istnieją dwa podejścia do rozwiązania tego problemu:
Dołączanie za pomocą prostego group-identifier, max-value-in-group
Zapytanie podrzędne
W tym podejściu najpierw znajdziesz group-identifier, max-value-in-group
(już rozwiązane powyżej) w podzapytaniu. Następnie dołączasz swoją tabelę do podzapytania z równością na obu group-identifier
i 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
Dołączanie w lewo ze sobą, dostrajanie warunków łączenia i filtrów
W tym podejściu wyszedłeś dołączyć do stołu ze sobą. Równość idzie w group-identifier
. Następnie 2 sprytne ruchy:
- Drugim warunkiem połączenia jest posiadanie wartości po lewej stronie mniejszej niż wartość po prawej
- Kiedy wykonasz krok 1, wiersze, które faktycznie mają maksymalną wartość, będą miały
NULL
po prawej stronie (jest toLEFT JOIN
, Zapamiętaj?). Następnie filtrujemy połączony wynik, pokazując tylko wiersze, w których prawa strona toNULL
.
W efekcie otrzymujesz:
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;
Wniosek
Oba podejścia przynoszą dokładnie ten sam wynik.
Jeśli masz dwa wiersze z max-value-in-group
dla group-identifier
, oba wiersze będą w wyniku w obu podejściach.
Oba podejścia są kompatybilne z SQL ANSI, dzięki czemu będą działać z twoim ulubionym RDBMS, niezależnie od jego "smaku".
Oba podejścia są również przyjazne dla wydajności, jednak Twój przebieg może się różnić (RDBMS, struktura DB, indeksy itp.). Jeśli więc wybierzesz jedno podejście z drugiego, benchmark . I upewnij się, że wybierzesz ten, który jest dla Ciebie najbardziej sensowny.