Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

SQL запрос MAX

Nick Belzur Ученик (78), на голосовании 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 выводит не имя одного игрока с максимальными очками, а имя нескольких игроков, как это исправить ?
Голосование за лучший ответ
Jurijus Zaksas Искусственный Интеллект (445781) 2 года назад
При помощи вложенных запросов. Как конкретно они реализованы в твоем диалекте и какая у тебя там структура таблиц (например, условие s.achievement_id = a.player_id выглядит диковато - либо у тебя там большие проблемы с неймингом, либо с логикой) - нам отсюда не видно, так что не жди какого-то готового кода. Если твой код в целом верен, то я бы просто добавил в конце = (select MAX(amount) from score). Но это неточно.
G Мыслитель (5876) 2 года назад
Обычно это делают таким способом:
 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 в зависимости от диалекта.
Black Afgano Просветленный (22302) 2 года назад
 SELECT p.* 
FROM achievement AS a
JOIN score AS s
ON a.id = s.achievement_id
JOIN player AS p
ON p.id = a.player_id
GROUP BY p.id
ORDER BY SUM(s.amount) DESC
LIMIT 1;
Похожие вопросы