Este é o maior problema de n por grupo que aparece com frequência no Stack Overflow.
Aqui está minha resposta usual:
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
;
Em outras palavras, dada a pontuação s, tente encontrar uma pontuação s2 para o mesmo jogador, mas com uma data anterior. Se nenhuma pontuação anterior for encontrada, então s será a primeira.
Re seu comentário sobre empates:Você tem que ter uma política para qual usar em caso de empate. Uma possibilidade é se você usar chaves primárias de incremento automático, aquela com o menor valor é a anterior. Veja o termo adicional na junção externa abaixo:
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
;
Basicamente, você precisa adicionar termos de desempate até chegar a uma coluna que seja única, pelo menos para o jogador em questão. A chave primária da tabela geralmente é a melhor solução, mas já vi casos em que outra coluna era adequada.
Em relação aos comentários que compartilhei com @OMG Ponies, lembre-se de que esse tipo de consulta se beneficia enormemente do índice correto.