На пръв поглед...
Всичко, от което се нуждаете, е GROUP BY
клауза с MAX
агрегатна функция:
SELECT id, MAX(rev)
FROM YourTable
GROUP BY id
Никога не е толкова просто, нали?
Току-що забелязах, че имате нужда от content
колона също.
Това е много често срещан въпрос в SQL:намерете всички данни за реда с някаква максимална стойност в колона за някакъв групов идентификатор. Чувал съм това много по време на кариерата си. Всъщност това беше един от въпросите, на които отговорих в техническото интервю за текущата ми работа.
Всъщност е толкова често срещано явление, че общността на Stack Overflow е създала един маркер само за справяне с въпроси като този:най-добрият-n-per-group .
По принцип имате два подхода за решаване на този проблем:
Присъединяване с прост group-identifier, max-value-in-group
Подзаявка
При този подход първо намирате group-identifier, max-value-in-group
(вече решено по-горе) в подзаявка. След това присъединявате вашата таблица към подзаявката с равенство на group-identifier
и 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
Ляво присъединяване със себе си, настройка на условията за присъединяване и филтри
При този подход вие оставихте да се присъедините към масата със себе си. Равенството влиза в group-identifier
. След това 2 интелигентни хода:
- Второто условие за присъединяване е, че стойността на лявата страна е по-малка от дясната
- Когато направите стъпка 1, редовете, които всъщност имат максималната стойност, ще имат
NULL
в дясната страна (това еLEFT JOIN
, помня?). След това филтрираме обединения резултат, показвайки само редовете, където дясната страна еNULL
.
Така че в крайна сметка получавате:
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;
Заключение
И двата подхода дават абсолютно същия резултат.
Ако имате два реда с max-value-in-group
за group-identifier
, двата реда ще бъдат в резултата и в двата подхода.
И двата подхода са съвместими с SQL ANSI, така че ще работят с любимата ви RDBMS, независимо от нейния „вкус“.
И двата подхода също са лесни за производителност, но вашият пробег може да варира (RDBMS, DB структура, индекси и т.н.). Така че, когато изберете един подход пред другия, сравнете . И не забравяйте да изберете този, който има най-голям смисъл за вас.