2016-03-02 75 views
0

我有一个名为学生像下面SQL Server表:如何从sql server中选择具有最大值的数据行?

enter image description here

我要选择的学生从各班最高分,这将产生这样的输出:

enter image description here

由于受到一些限制,我无法确定表中将存在多少个唯一的类名。我的存储过程是:

create procedure selectBestStudent 
    as 
    begin 
    select Name, max(TestScore) 
    from [TestDB1].[dbo].[StudentTest] 
    group by Name 
    end 

但结果是错误的。任何想法?

+0

见:http://dba.stackexchange.com/questions/1002/how-to-get-the-max-row –

+0

[从每个组中抓取具有最高值的行的可能的复制?](http://stackoverflow.com/questions/9180283/grabbing-the-row-with-the-highest-value-from-each-group) –

回答

3

可以使用ROW_NUMBERPARTITION BY

SELECT Name, Class, TestScore 
FROM (
    SELECT Name, Class, TestScore, 
     ROW_NUMBER() OVER (PARTITION BY Class 
          ORDER BY TestScore DESC) AS rn 
    FROM StudentTest) AS t 
WHERE t.rn = 1 

ROW_NUMBER列举每个Class分区中记载:ORDER BY条款保证具有最大TestScore值的记录被赋予相等的值1。

注意:要处理领带,您可以使用RANK代替ROW_NUMBER。这样你可以得到全部同学共享相同最大TestScore相同Class

+0

你可以尝试添加一个COUNT(*)OVER(PARTITION BY类)' –

+0

谢谢:)我真的很感激你的回复:) –

+1

@Downvoter关注评论? –

1

您也可以实现这一目标NOT EXISTS()

SELECT * FROM Student s 
WHERE NOT EXISTS(select 1 FROM Student t 
       where t.class = s.class 
         and t.testScore > s.testScore) 

这将仅选择不具有行与testScore较高值的那些行

1

我想你一定有如果班级中有多个具有相同分数的人,则“分组依据”和MAX()存在问题。

我解决了它,如果你还不知道这是什么,你可以看看here。它比开始时看起来更容易!

我知道这可能是一种可怕的方式来做到这一点,但它很容易理解,它的工作原理! :d

USE [TestDB] 
GO 

DECLARE @class char(10), @testscore int; 
DECLARE @result Table 
(
    Name char(10), 
    Class char(10), 
    TestScore int 
); 
-- Get Classes and their Maxima 
DECLARE TestScore_cursor CURSOR FOR SELECT [class], MAX([testscore]) FROM [student] GROUP BY [class]; 

OPEN TestScore_cursor; 

-- Perform the first fetch. 
FETCH NEXT FROM TestScore_cursor INTO @class, @testscore; 

-- Check @@FETCH_STATUS to see if there are any more rows to fetch. 
WHILE @@FETCH_STATUS = 0 
BEGIN 
    -- Search Students by Class and Score and add them to tempTable @result 
    INSERT INTO @result SELECT [name], [class], [testscore] From [student] where [testScore] = @testscore AND [class] = @class; 

    FETCH NEXT FROM TestScore_cursor INTO @class, @testscore; 
END 

-- Show the Result 
SELECT * FROM @result; 

CLOSE TestScore_cursor; 
DEALLOCATE TestScore_cursor; 
GO 
相关问题