Обычно это делают таким способом:
SELECT p.nickname, s.amount
FROM player p inner join achievement a on p.id = a.player_id
INNER JOIN score s on s.achievement_id = a.player_id --это действительно очень странное условие соединения
WHERE s.amount =
( SELECT MAX(s1.amount)
FROM score s1
INNER JOIN player p1 on s1.player_id=p1.id
WHERE p.id=p1.id)
Смысл в том, чтобы в подзапросе с функцией MAX
1) его внутренний идентификатор(
p1.id ) сущности совпадал с внешним (
p.id ) и
2) была минимальная связка таблиц от хранящей искомый максимум до хранящей объект с нужным идентификатором. Так что поправишь подзапрос для этих условий.
У таких небольших запросов часто внутри подзапроса почти то же самое, что и снаружи, только с функцией MAX в SELECT-е и условием совмещения id объекта внутри и снаружи. Невыполнение пункта (1) - распространённая ошибка. Также важно делать внутренние и наружные псевдонимы таблиц явно различимыми.
Но можно и твоим запросом попробовать получить результат добавлением внизу ORDER BY MAX(s.amount) DESC и limit 1, либо top 1 в зависимости от диалекта.
SELECT p.nickname , MAX(s.amount)
FROM player p
join achievement a on p.id = a.player_id
join score s on s.achievement_id = a.player_id
GROUP by p.nickname
HAVING MAX(s.amount)
SQL выводит не имя одного игрока с максимальными очками, а имя нескольких игроков, как это исправить ?