I am beginner in database. I am practicing on mySQL. I have two tables:
STUDENTS
sno | sName | age
ENROLL
sno | cno
I want a list of all students who have enrolled in more than one course. When i tried this:
select distinct s.* from student s, enroll e
where ((s.sno = e.sno) and (count(e.sno)>1));
i get this error:
"Invalid Use of group function"
Can you please tell me why I cant use count in where clause or what exactly is the problem here? Thanks in advance.
edit: This is not a homework question (professor has already posted the solution), I am struggling with the concept.
You can only use aggregate functions like COUNT()
in a HAVING
clause, or in the SELECT
clause when a GROUP BY
is used. The WHERE
clause operates on rows that come from the FROM
clause. No aggregation has taken place, so there is no way for the aggregate functions to be meaningful.
It looks like what you want to do is find from the ENROLL table all students that appear more than once. Then you want to get more details about those students. There are potentially many ways to do this, but I'd recommend a subquery.
SELECT s.*
FROM student AS s
JOIN (
SELECT e.sno
FROM enroll AS e
GROUP BY e.sno
HAVING COUNT(*) > 1
) AS e
ON e.sno = s.sno
ORDER BY s.age DESC
LIMIT 10
The subquery there after JOIN
does that first calculation (which students have multiple rows in ENROLL) and basically produces a pseudo-table with a list of student IDs. Since we're doing an inner join, only rows in the STUDENT table that have an sno
in our subquery will show up. That's basically taken care of by the ON
clause.
Since you said in a comment that you want to be able to apply additional conditions on the students, I've added in some example code where that would happen. Since that information comes from the STUDENT table, it can be done outside the subquery. You didn't specifically specifically what "oldest students" mean, so I've just assumed you wanted the 10 oldest enrolled in multiple courses. You should be able to adjust based on your needs.
Let me know if any of this doesn't make sense and I'll try to explain in more detail.
You can use this:
SELECT aa.sno, aa.sName, aa.age
FROM students AS aa
INNER JOIN (
SELECT sno, COUNT(*)
FROM enroll
GROUP BY sno
HAVING COUNT(*) > 1
) AS _aa
ON aa.sno = _aa.sno;
You cannot use COUNT
in the WHERE
clause, instead you have to use HAVING
:
The HAVING clause was added to SQL because the WHERE keyword could not be used with aggregate functions.
Furthermore you want to GROUP BY
student. So the resulting query is:
SELECT s.sno, s.sName
FROM STUDENTS s INNER JOIN ENROLL e on s.sno=e.sno
GROUP BY s.sno, s.sName
HAVING COUNT(*)>1;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.