2016-03-02 41 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 
相關問題