Jest to największy problem na grupę, który często pojawia się na Stack Overflow.
Oto moja zwykła odpowiedź:
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
;
Innymi słowy, mając dane s, spróbuj znaleźć wynik s2 dla tego samego zawodnika, ale z wcześniejszą datą. Jeśli nie zostanie znaleziony wcześniejszy wynik, s jest najwcześniejszym.
Odpowiedz na swój komentarz na temat krawatów:Musisz mieć politykę, której użyć w przypadku remisu. Jedną z możliwości jest to, że jeśli używasz automatycznego przyrostu kluczy podstawowych, ten z najmniejszą wartością jest wcześniejszy. Zobacz dodatkowy termin w sprzężeniu zewnętrznym poniżej:
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
;
Zasadniczo musisz dodać terminy rozstrzygania remisów, dopóki nie dojdziesz do kolumny, która na pewno będzie unikalna, przynajmniej dla danego gracza. Klucz główny tabeli jest często najlepszym rozwiązaniem, ale widziałem przypadki, w których odpowiednia była inna kolumna.
Jeśli chodzi o komentarze, które podzieliłem się z @OMG Ponies, pamiętaj, że tego typu zapytania bardzo korzystają z właściwego indeksu.