Reputation: 11
Trying to make a query that selects courses to take next quarter that you have already taken the prerequisite for. What makes it difficult for me is if there are multiple prerequisites for a course and you have already completed one.
The two tables are Record(Student, Course) and Prerequisite(Course, Prereq)
My query attempt that works but very slow:
select r.Student, p.Course
from Record r, Prerequisite p where r.Course = p.Prereq and p.Course not in
( select Course from (select r.Student, p.Course from Record r, Prerequisite p
where r.Course <> p.Prereq) a where a.Student = r.Student);
Any help would be great!
Sample data
CREATE TABLE Prerequisite (Course CHAR(32), Prereq CHAR(32));
CREATE TABLE Record (
Student CHAR(32),
Course CHAR(32),
PRIMARY KEY (Student, Course)
);
INSERT INTO Prerequisite VALUES ('Class 3', 'Class 1');
INSERT INTO Prerequisite VALUES ('Class 6', 'Class 4');
INSERT INTO Prerequisite VALUES ('Class 4', 'Class 1');
INSERT INTO Prerequisite VALUES ('Class 4', 'Class 3');
INSERT INTO Prerequisite VALUES ('Class 8', 'Class 2');
INSERT INTO Prerequisite VALUES ('Class 8', 'Class 6');
INSERT INTO Prerequisite VALUES ('Class 5', 'Class 2');
INSERT INTO Prerequisite VALUES ('Class 9', 'Class 8');
INSERT INTO Prerequisite VALUES ('Class 7', 'Class 5');
--added Class 10 requires Class 1 and Class 2
INSERT INTO Prerequisite VALUES ('Class 10', 'Class 1');
INSERT INTO Prerequisite VALUES ('Class 10', 'Class 2');
INSERT INTO Record VALUES ('Bob', 'Class 1');
INSERT INTO Record VALUES ('Jan', 'Class 2');
--Bob Takes both Class 1 and Class 2 thus he can take Class 10
INSERT INTO Record VALUES ('Bob', 'Class 2');
So result should be
Bob | Class 3
Jan | Class 5
Bob | Class 5
Bob | Class 10
edit: small sample data added
edit2: see the comments below for additional details
edit3: Just realized my solution is not working while looking over Mhai's new solution and making a test case that showed it wasn't working, mine didn't work for that case either.
Updated the sample data with a new test case, that is when you have a student that has taken both prerequisites for a class, they should take that class.
Upvotes: 1
Views: 167
Reputation: 26784
Try
SELECT r.Student, p.Course FROM Record r
JOIN Prerequisite p
ON r.Course = p.Prereq
LEFT JOIN (
select r.Student, p.Course FROM Record r
JOIN Prerequisite p
ON p.Prereq<>r.Course)x
ON x.Student = r.Student
WHERE p.Course IS NULL
SELECT r.Student,p.Course,pp.Prereq FROM Record r
JOIN Prerequisite p
ON r.Course = p.Prereq
JOIN Prerequisite pp
ON
p.Course=pp.Course
GROUP BY p.Course HAVING COUNT(*)=1
This will find all records with just 1 requirement
Upvotes: 2
Reputation: 110
select r.Student, p.Course
from Record r inner join Prerequisite p on p.Prereq = r.course where not exists(
( select pr.Course from Prerequisite pr inner join records rr on rr.student=r.student
where pr.Prereq =r.course ))
Try this, use NOLOCK if you afford to have dirty records.
Upvotes: 0