Toto je největší problém-n-per-group, který se na Stack Overflow často vyskytuje.
Zde je moje obvyklá odpověď:
select
p.name player,
s.date first_score,
s.points points
from players p
join scores s
on s.player_id = p.id
left outer join scores s2
on s2.player_id = p.id
and s2.date < s.date
where
s2.player_id is null
;
Jinými slovy, při daném skóre s se pokuste najít skóre s2 pro stejného hráče, ale s dřívějším datem. Pokud není nalezeno žádné dřívější skóre, pak s je nejstarší.
K vašemu komentáři ohledně remíz:Musíte mít zásady, které se mají použít v případě remízy. Jednou z možností je, že pokud použijete automaticky se zvyšující primární klíče, ten s nejmenší hodnotou je ten dřívější. Viz další termín ve vnějším spojení níže:
select
p.name player,
s.date first_score,
s.points points
from players p
join scores s
on s.player_id = p.id
left outer join scores s2
on s2.player_id = p.id
and (s2.date < s.date or s2.date = s.date and s2.id < s.id)
where
s2.player_id is null
;
V zásadě musíte přidávat výrazy pro nerozhodný výsledek, dokud se nedostanete na sloupec, který je zaručeně jedinečný, alespoň pro daného hráče. Primární klíč tabulky je často nejlepším řešením, ale viděl jsem případy, kdy byl vhodný jiný sloupec.
Pokud jde o komentáře, které jsem sdílel s @OMG Ponies, nezapomeňte, že tento typ dotazu velmi těží ze správného indexu.