Reputation: 183
I have a database that stores exam records: tbl_exams
stores the id and name of exams - there are only 9 exams and so only 9 records in this table as the exams are fixed and do not change. tbl_exam_details
stores all the details for an exam entry, and includes the corresponding id from tbl_exams
- there is a foreign key constraint for this. What I'm trying to do is create a query that returns rows only if all 9 exams have been taken by a certain student and the pass_or_fail
field is '1' - I use tinyint(1)
to store 1 which is pass, or 0 which is fail). This is essentially to check if all 9 exams have been passed.
This is what I have so far, however it is returning rows even when the student has only completed one or two exams:
SELECT tbl_exam_details.student_id, exam_name, exam_date, pass_or_fail FROM tbl_exam_details
INNER JOIN tbl_exams ON tbl_exams.exam_id = tbl_exam_details.exam_id
WHERE student_id = 1 AND pass_or_fail = 1
AND tbl_exam_details.exam_id IN (1, 2, 3, 4, 5, 6, 7, 8, 9)
ORDER BY exam_details_id
What I need is for the query to only return rows once all 9 exams have been passed. So, if a student has passed 8 exams, the query should return 0 rows. If anyone could help me out it would be greatly appreciated.
Upvotes: 0
Views: 114
Reputation: 48177
SELECT ted.student_id,
exam_name,
exam_date,
pass_or_fail
FROM tbl_exam_details ted
INNER JOIN tbl_exams
ON tbl_exams.exam_id = ted.exam_id
WHERE student_id = 1
AND (SELECT COUNT(*)
FROM tbl_exam_details ted2
WHERE ted2.pass_or_fail = 1
AND ted2.student_id = ted.student_id
) = 9 -- mean this student pass 9 exams
ORDER BY exam_details_id
Upvotes: 2
Reputation: 1269483
Is this what you want?
SELECT ed.student_id
FROM tbl_exam_details ed
WHERE ed.student_id = 1 AND ed.pass_or_fail = 1 AND
ed.exam_id IN (1, 2, 3, 4, 5, 6, 7, 8, 9)
GROUP BY ed.student_id
HAVING COUNT(*) = 9; -- or maybe COUNT(DISTINCT exam_id) = 9
This returns the student ids that have passed the 9 exams. It doesn't include any other information.
Upvotes: 1
Reputation: 11195
You can group_concat for a full list...
select x1.*
from
(
select t1.*, group_concat(distinct exam_id order by exam_id separator '|') as x_list
from tbl_exam_details t1
where pass_or_fail = 1
group by student_id
) x1
where x_list = '1|2|3|4|5|6|7|8|9'
Upvotes: 0