2015-10-19 2 views
0

есть таблица в базе данных SQL, называемая Игроки: Игроки (ID, имя, возраст, пол, статистика) где ID - это первичный ключ.Как найти следующий SQL-запрос?

Теперь я хочу написать запрос, чтобы найти следующие результаты: Для каждого возраста найдите имя и возраст игрока (ов) с наибольшим счетом среди всех игроков этого возраста.

Я написал следующий запрос:

SELECT P.name, P.age 
FROM Players P 
WHERE P.score = (SELECT MAX(P2.score) FROM Players P2) 
GROUP BY P.age, P.name 
ORDER BY S.age 

Однако результат вышеупомянутого запроса является списком игроков с наибольшим количеством очков среди всех игроков во всех возрастах, а не для каждого возраста.

Затем я изменил мой запрос к следующему:

SELECT P.name, P.age, MAX(P.score) 
FROM Players P 
GROUP BY P.age, P.name 
ORDER BY P.age 

Однако второй запрос я написал дает список игроков с каждым возрастом, но и для каждого возраста, есть не только игроки с самым высоким но и других игроков с более низкими баллами в этой возрастной группе.

Как исправить код логики/запроса?

Спасибо!

ответ

0

Ваш первоначальный запрос довольно близко. Вам просто нужно изменить подзапрос быть связанным подзапрос и удалить GROUP BY пункт:

SELECT P.name, P.age 
FROM Players P 
WHERE P.score = (SELECT MAX(P2.score) FROM Players P2 WHERE p2.age = p.age) 
ORDER BY P.age; 

Аналитические функции ранжирований являются еще одним очень жизнеспособным методом для обработки этого вопроса. Оба метода могут использовать индекс на Players(age, score). Это также требует индекса на Players(score). С этим индексом это должно иметь лучшую производительность на больших наборах данных.

+0

Я вижу, теперь он работает очень хорошо. Спасибо! – user118464

1

Вы можете использовать rank для этого.

select name, age 
from (
SELECT *, 
rank() over(partition by age order by score desc) rnk 
FROM Players) t 
where rnk = 1 
+0

Спасибо! Я поставил вышеуказанный запрос на сервер Oracle, и он говорит «Недопустимый SQL. Не допускается!» ... Также есть ли способ избежать «ранжирования»? Большое спасибо! – user118464

+0

, какую версию Oracle вы используете? –

+0

@ user118464: это, безусловно, правильный SQL-запрос для Oracle. И «недопустимый» - это ** не ** действительное сообщение об ошибке Oracle. Вы уверены, что используете Oracle? И что такое ** точное сообщение об ошибке, которое вы получаете? Вы также не «отправляете запрос на сервер Oracle» - вы запускаете его с помощью SQL-клиента. Какой SQL-клиент вы используете? SQL * Plus? Разработчик SQL? Что-то другое? –

0

Вы также можете попробовать.

SELECT p.name, p.age, p.score 
FROM players p 
INNER JOIN 
    (SELECT `age`, MAX(`score`) AS Maxscore 
    FROM players 
    GROUP BY `age`) pp 
ON p.`age` = pp.`age` 
AND p.`score` = pp.Maxscore; 
0

Попробуйте это позволит решить проблему:

select p1.name,p1.age,p1.score from players p1 where p1.score = 
(SELECT max(score) from players where age = p1.age) group by p1.age; 

Если вы требовали, чтобы все записи, имеющие такой же максимальный балл: Тогда вы будете использовать это. Я проверил оба запроса на моем localhost.

SELECT p1.name,p1.age,p1.score FROM players p1 
WHERE p1.score IN (SELECT MAX(score) FROM players GROUP BY age) 
Смежные вопросы