0

I have a Students table and a Grades table.

  • Students has columns student_id(primary key), name, date_of_birth, address, email, and level.
  • Grades has columns student_id(primary/foreign key), course_id(primary/foreign key), and grade.

"Grades" looks like this:

student_id|course_id|grade
===========================
    1     |    1    |   A
    1     |    2    |   B
    1     |    3    |   A
    3     |    1    |   F
    3     |    3    |   C
    .
    .
    .
    .

This isn't the whole table, but you get the gist. I'm trying to write a query which SELECTS the name of a student and that student's highest grade. As I'm new to SQL this one is a little confusing for me. My attempt so far is this:

SELECT "Students".name, "Grades".grade FROM "Students" INNER JOIN
"Grades" ON "Students".student_id = "Grades".student_id GROUP BY name, 
grade HAVING MIN(grade) <= 'F';

It's wrong, and I know why, but I'm not sure where to go from here.

Omar Kadery
  • 165
  • 1
  • 4
  • 14

2 Answers2

0
SELECT Students.name, min(Enroll.grade)  
  FROM Students 
 INNER JOIN Enroll 
    ON Students.student_id = Enroll.student_id 
 GROUP BY name, 
paparazzo
  • 44,497
  • 23
  • 105
  • 176
0

how do I select the ones with the highest value in a certain column?

Bold emphasis mine.

GROUP BY is good to get the maximum for a single column. To get the rows with the maximum, you'd have to do more.

The simple solution in Postgres to get one row per student is with DISTINCT ON:

SELECT *
FROM   students s
JOIN  (
   SELECT DISTINCT ON (student_id) *
   FROM   grades
   ORDER  BY student_id, grade
   ) g USING (student_id);

The lowest happens to be the "highest" grade here.
To get the ones with the highest value (possible plural), use the window function rank():

SELECT *
FROM   students s
JOIN  (
   SELECT *, rank() OVER (PARTITION BY student_id ORDER BY grade) AS rnk
   FROM   grades
   ) g USING (student_id)
WHERE  g.rnk = 1;
Community
  • 1
  • 1
Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228