0

I have a table which has 3 columns StudentID, Score and ClassNumber. What I need now is to select top 5 students of each Class (according to their Score result).

For example if there are 20 students in Class1, 40 students in Class2 and students in Class3, I need to select 15 top score students for each Class(5 for Class1, 5 for Class2, 5 for Class3)

How can I do this in one SQL query?

4
  • What rdbms are you using? Commented Mar 21, 2018 at 10:22
  • For which database and version ? For Oracle and SqlServer you have the row_number window function that can group and enumerate records within the group. Then you can query the top(x) from each. Commented Mar 21, 2018 at 10:24
  • @AmirPelled: window functions are not limited to Oracle and SQL Server. Every modern DBMS supports them. Even MySQL will arrive in the 21st century with the upcoming version 8. Commented Mar 21, 2018 at 10:26
  • Please edit your question and add some sample data and the expected output based on that data. Formatted text please, no screen shots. (edit your question - do not post code or additional information in comments) Commented Mar 21, 2018 at 10:26

2 Answers 2

1

Do you mean somthing like this?

with tmp as ( select ClassNumber, StudentID, Score, row_number() over (partition by ClassNumber order by Score desc) row_num, from Student s ) select ClassNumber, StudentID, Score from tmp where row_num <= 5 order by ClassNumber 
Sign up to request clarification or add additional context in comments.

2 Comments

Did you consider scenario where more than one student have same score?
Its select only 5 students for class, Test it. If there is any preference for this case - can add the relevant column to the order section within the row_number() function.
1

Solution in MYSQL :

SELECT StudentID, Score, ClassNumber FROM (SELECT StudentID, Score, ClassNumber, @class_rank := IF(@current_class = classNumber, @class_rank + 1, 1) AS class_rank, @current_class := ClassNumber FROM student ORDER BY ClassNumber, score DESC ) ranked WHERE class_rank <= 5; 

Solution in SQL SERVER:

select ClassNumber, StudentID, Score from ( select ClassNumber, StudentID, Score, dense_rank() over (partition by ClassNumber order by Score desc) ranking from Student s ) as t where ranking <= 5 order by ClassNumber 

2 Comments

It's working perfectly this way. Thanks so much Nishant.
If you find it useful please accept the answer.@Julia

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.