0

I'm trying to return the name & grade of the student with the third highest assessment grade. I'm currently getting the right answer, but I feel like there's a better way to do it.

Dataset

CREATE TABLE Student( Student_ID INT, Student_Name VARCHAR(10) ) INSERT INTO Student (Student_ID, Student_Name) VALUES (1,'Alex'),(2, 'Brett1'),(3,'Cora'),(4,'David'),(5,'Eleanor'),(6,'Brett2')

CREATE TABLE Grades( Student_ID INT, Assignment_ID INT, Grade INT ) INSERT INTO Grades (Student_ID, Assignment_ID, Grade) VALUES (1,10,90),(2,10,85),(3,10,75),(4,10,74),(1,11,80),(2,11,81),(4,11,88),(6,11,86),(2,12,84)

Attempted Solution

SELECT top 1 s.Student_Name, g.Grade FROM Student s INNER JOIN Grades g on s.Student_ID=g.Student_ID WHERE g.Grade < 88 ORDER BY Grade DESC

Without the (WHERE g.Grade<88) it returns the top 3 results, this was a manual way to fix the issue

Thanks in advance~!

matrixfox
  • 83
  • 1
  • 9

3 Answers3

2

for obtain only the 3rd you could use the TOP 1 reverted of the top 3

  select top 1 Student_name, Grade 
  from ( 
    SELECT top 3 s.Student_Name, g.Grade
      FROM Student s
      INNER JOIN Grades g on s.Student_ID=g.Student_ID
      ORDER BY Grade DESC ) t
      order by Grade asc
ScaisEdge
  • 131,976
  • 10
  • 91
  • 107
  • 1
    This has the advantage that if there only two rows in the inner query it will return the second row. This may or may not be what you desired but it is a subtlety to understand. – Sean Lange Feb 07 '18 at 20:18
2

"Newer" SQL Server versions (SQL Server 2012+):

SELECT s.Student_Name, g.Grade
FROM Student s
INNER JOIN Grades g on s.Student_ID=g.Student_ID
ORDER BY Grade DESC
OFFSET 2 FETCH FIRST 1 ROW ONLY 
jarlh
  • 42,561
  • 8
  • 45
  • 63
0

Use ROW_NUMBER window function

;with cte
AS (
SELECT s.Student_Name, g.Grade ,
RN = row_number()over(order by Grade desc)
FROM Student s
 INNER JOIN Grades g on s.Student_ID=g.Student_ID 
)
Select *
From cte
Where RN = 3
Mazhar
  • 3,797
  • 1
  • 12
  • 29