Dit is het grootste probleem per groep dat vaak voorkomt op Stack Overflow.
Dit is mijn gebruikelijke antwoord:
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
;
Met andere woorden, gegeven score s, probeer een score s2 te vinden voor dezelfde speler, maar met een eerdere datum. Als er geen eerdere score wordt gevonden, dan is s de vroegste.
Over je opmerking over gelijkspel:je moet een beleid hebben waarvoor je het moet gebruiken in geval van gelijkspel. Een mogelijkheid is dat als u automatisch oplopende primaire sleutels gebruikt, degene met de minste waarde de eerdere is. Zie de aanvullende term in de outer join hieronder:
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
;
In principe moet je tiebreaker-termen toevoegen totdat je bij een kolom komt die gegarandeerd uniek is, in ieder geval voor de gegeven speler. De primaire sleutel van de tabel is vaak de beste oplossing, maar ik heb gevallen gezien waarin een andere kolom geschikt was.
Wat betreft de opmerkingen die ik heb gedeeld met @OMG Ponies, onthoud dat dit type zoekopdracht enorm profiteert van de juiste index.