2017-05-28 29 views
2

我正在使用SQL Server数据库。通过返回太多行限制最大值和组

鉴于以下查询,我试图获得每个班级的最高分数。 Scores表有两行50行,所以我总共需要2行。但是,因为我有Scores.Id,所以它返回Scores的每一行,因为Scores.Id是唯一的。当然,简单的解决方案是删除Scores.Id列,但我需要知道Scores.Id进行其他查找。

SELECT 
    Class_Id, Scores.Id, MAX(Scores.ClassScore) AS Score 
FROM 
    Classes 
INNER JOIN 
    Scores ON Classes.Id = Scores.Class_Id     
GROUP BY 
    Scores.Class_Id, Scores.Id 

回答

3

最高得分的标识码(class_id)简直是

select class_id, max(classScore) score from scores 
group by class_id 

然后,如果您需要知道哪些在得分表中的行有最高分可以加入。如果每班有多个相同的最高分数,则可能会得到两个以上的行。

select id, class_id, classscore from 
scores s 
inner join 
(
    select class_id, max(classScore) score from scores 
    group by class_id 
) 
t 
on t.class_id = s.class_id and t.score = s.classScore 

或者我可能会使用一个CTE

with maxScores as 
(
    select class_id, max(classScore) score from scores 
    group by class_id 
) 
select id, class_id, classscore from 
scores s 
on maxScores.class_id = s.class_id and maxScores.score = s.classScore 
+0

其他的答案都是有效的。有趣的是(对于非常少量的测试数据),我的查询给出了最新的查询计划,但RANK函数提供了最快的查询(添加索引之后)。 – Phil

3

这是你想要的吗?

select s.* 
from (select s.*, 
      max(s.classscore) over (partition by s.class_id) as max_classscore 
     from scores s 
    ) s 
where classscore = max_classscore; 

鉴于您需要的信息,加入到Classes是多余的。

2

这看起来像对rank窗口功能的工作:

SELECT Class_Id, Id, Score 
FROM (SELECT Class_Id, Scores.Id AS Id, Score, 
       RANK() OVER (PARTITION BY Class_Id, Scores.Id 
          ORDER BY Score DESC) AS rk 
     FROM Classes 
     JOIN Scores ON Classes.Id = Scores.Class_Id) t 
WHERE rk = 1