2015-10-19 94 views
0

SQL数据库中有一个表,名为Players: 玩家(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:这绝对是Oracle的有效SQL查询。并且“不允许”是**不是**有效的Oracle错误消息。您是否确定*您正在使用Oracle?你得到的**确切**错误信息是什么?您也不会“查询到Oracle服务器” - 您使用SQL客户端运行它。你正在使用哪个SQL客户端?在SQL * Plus? SQL Developer?还有别的吗? –

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; 

如果您需要将相同的具有最高得分的所有记录: 然后你会使用这个。我测试了我的本地主机上的查询。

SELECT p1.name,p1.age,p1.score FROM players p1 
WHERE p1.score IN (SELECT MAX(score) FROM players GROUP BY age)