Reputation: 15
I have a table with the schema below:
+---------+--------+
|studentId | course |
+---------+--------+
|1 | 2 |
|1 | 3 |
|1 | 4 |
|1 | 5 |
|2 | 4 |
|2 | 5 |
+---------+--------+
and I want to perform a query to get student Ids that don't have course 2 and 3
select * from students where course not in (2,3);
but it returns Students IDs 1 and 2 and I want it to return Student ID 2 only.
How do I do that?
Upvotes: 1
Views: 134
Reputation: 16691
I would recommend using NOT IN and writing a subquery that pulls for each student who is taking courses 2 or 3. That is, if you are looking for students who are not taking course 2 or 3. If you are looking to exclude students who are taking BOTH courses, this will need to change a little bit. Let me know if that is the case.
Start by writing the subquery, which is easy enough:
SELECT *
FROM students
WHERE course = 2 OR course = 3
Then, you can select from your table again using the NOT IN operator:
SELECT DISTINCT studentid
FROM students
WHERE studentid NOT IN (SELECT studentid
FROM students
WHERE course = 2 OR course = 3);
And it works!
Upvotes: 0
Reputation: 33935
SELECT DISTINCT x.studentid
FROM student x
LEFT
JOIN
( SELECT studentid
FROM student
WHERE course IN(2,3)
GROUP
BY studentid
HAVING COUNT(*) = 2 ) y
ON y.studentid = x.studentid
WHERE y.studentid IS NULL;
(of course, it's highly unlikely that a table holding students and courses would be called student
. enrolment
might be a better title)
Upvotes: 0
Reputation: 1236
This answers assumes that OP wants to filter out students that have either course 2 or course 3 or both of them set.
At first, find all students, who have course 2 or 3
SELECT DISTINCT studentId
FROM students
WHERE course IN (2,3)
Then, find all students, who are not in that list
SELECT *
FROM students
WHERE studentId NOT IN (...)
If you only want to return a list of studentIds, without their courses, replace *
with DISTINCT studentId
.
Put those together:
SELECT DISTINCT studentId
FROM students
WHERE studentId NOT IN (
SELECT DISTINCT studentId
FROM students
WHERE course IN (2,3)
)
Upvotes: 2
Reputation: 405
JR's query will perform poorly MySQL < 5.6 and only performs an OR not an AND on course.
Try this:
SELECT
id
FROM foo AS missingfoo
LEFT JOIN (
SELECT id FROM foo AS foo1
JOIN foo AS foo2 USING (id)
WHERE foo1.course=2
AND foo2.course=3
) AS z
USING (id) WHERE z.id IS NULL GROUP BY id;
Upvotes: -1
Reputation: 32392
Another query using having
to filter out students that have courses 2 or 3
select studentId
from students
group by studentId
having sum(course in (2,3)) = 0
Upvotes: 1
Reputation: 6132
You could do it like this:
select * from students where studentId not in -- exclude all students from course 2 & 3
(
--find all the students in course 2 & 3
select distinct studentId --could be duplicates might as well grab a distinct list.
from students
where course in (2,3)
)
Upvotes: 2
Reputation: 7679
This should work:
select
*
from
students s
where
not exists ( select
1
from
students ss
where
ss.studentID = s.studentID
and ss.course in (2,3));
Upvotes: 0