Disclaimer: I'm an SQL newb and this is for a class, but I could really use a poke in the right direction.
I've got these three tables:
student(_sid_, sname, sex, age, year, gpa)
section(_dname_, _cno_, _sectno_, pname)
enroll(_sid_, grade, _dname_, _cno_, _sectno_)
(primary keys denoted by underscores)
I'm trying to write an Oracle-compatible SQL query that returns a table with the student's name (student.sname
) that has the highest gpa in each section (that's including section.cno
and section.sectno
) as well as all the other attributes from section
.
I've managed to use an aggregate query and GROUP BY
to get the maximum GPA for each section:
SELECT MAX(s.gpa), e.cno, e.sectno
FROM enroll e,
student s
WHERE s.sid = e.sid
GROUP BY e.cno, e.sectno
Let alone the other section
attributes, I can't even figure out how to tack on the student name (student.sname
). If I add it to the SELECT
clause, it has to be included in GROUP BY
which messes up the rest of the query. If I use this entire query inside the WHERE
or FROM
clause of an outer query, I can only access the three fields in the table, which isn't that much use.
I know you can't give me the exact answer, but any hints would be appreciated!
Assuming Oracle 9i+, to get only one of the students with the highest GPA (in the event of ties) use:
WITH summary AS (
SELECT e.*,
s.name,
ROW_NUMBER() OVER(PARTITION BY e.cno, e.sectno
ORDER BY s.gpa DESC) AS rank
FROM ENROLL e
JOIN STUDENT s ON s.sid = e.sid)
SELECT s.*
FROM summary s
WHERE s.rank = 1
Non CTE equivalent:
SELECT s.*
FROM (SELECT e.*,
s.name,
ROW_NUMBER() OVER(PARTITION BY e.cno, e.sectno
ORDER BY s.gpa DESC) AS rank
FROM ENROLL e
JOIN STUDENT s ON s.sid = e.sid) s
WHERE s.rank = 1
If you want to see all students who tied for GPA, use:
WITH summary AS (
SELECT e.*,
s.name,
DENSE_RANK OVER(PARTITION BY e.cno, e.sectno
ORDER BY s.gpa DESC) AS rank
FROM ENROLL e
JOIN STUDENT s ON s.sid = e.sid)
SELECT s.*
FROM summary s
WHERE s.rank = 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With