简体   繁体   中英

Using count in where clause : invalid use of group function

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM