Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Using the SUM() in the ON Clause of the Join

I have 3 tables named students, student_courses and grades. And for each student I need to calculate their overall GPA. So I’m a bit stuck. 🙁

students table

student_id student_name
77 Pepe LePew

student_courses

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

student_id course_id percent_grade
77 101 95.7
77 202 85.9
77 303 77.1
77 404 66.6

grades

from_percent to_percent letter_grade GPA
0 69 F 0
70 72 C- 1.67
73 76 C 2.0
77 79 C+ 2.33
80 82 B- 2.67
83 86 B 3.0
87 89 B+ 3.33
90 92 A- 3.67
93 96 A 4.0
97 100 A+ 4.0

Here’s my query that is getting an error. (Error Code 1111. Invalid use of group function) I happen to be using MySQL but would be happy to get a standard SQL solution.

SELECT student_id, student_name,
(select g.GPA      
 from course_student AS cs    
 inner join Grades AS g ON (sum(cs.percent_grade) / count(*)) BETWEEN g.from_percent AND g.to_percent
 where cs.student_id = students.id) As GPA 
FROM students 

The expected result would be a listing of all of the students in the student table and their corresponding overall GPA

student_id GPA
77 2.67

Update 1.

I just got it to work for a single student. But I need it to work for all of the students in the students table. Here’s the code for a single student.

select g.GPA, g.from_percent, g.to_percent
 from course_student AS cs    
 inner join Grades AS g 
 where cs.student_id = 77
 group by g.GPA, g.from_percent, g.to_percent
 HAVING (sum(cs.percent_grade) / count(*)) BETWEEN g.from_percent AND g.to_percent 

>Solution :

We can create a StudentGrades CTE that groups by student and calculates the average grade from all of their courses. Then we can then use AvgGrade to join on the grades table.

WITH StudentGrades as
(
  SELECT s.student_id, s.student_name, SUM(percent_grade) as TotalGrade, count(*) as CourseCount, CAST(SUM(percent_grade) / count(*) AS INT)  as AvgGrade
  FROM students  s
  INNER JOIN student_courses c on s.student_id=c.student_id
  GROUP BY s.student_id, s.student_name
)
SELECT sg.student_id, sg.student_name, g.GPA
FROM StudentGrades sg
INNER JOIN grades g on g.from_percent <= sg.AvgGrade AND g.to_percent >= sg.AvgGrade

fiddle

student_id student_name GPA
69 Bart McEndree 4
77 Pepe LePew 2.67
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading