I need to build an SQL query in MySQL to solve a problem as part of an assignment for class. I've been working at this problem for awhile, but I'm having a hard time figuring out how to structure this query properly. I'm rather new to the SQL language and databases in general and I'm stumped on this question. I have posted what I've come up with so far, but unfortunately I have not been able to get the results I'm looking for. If anyone could give me some guidance on how to accomplish this I would greatly appreciate it.
Here's what my table structure looks like:
course(cid, fid, room)
enroll(cid, sid, grade)
faculty(fid, fname, dept, rank)
student(sid, sname, major, credits)
Here's the query I need to build:
Show the faculty id and faculty name for all faculty that have taught all computer science majors (major = 'CSC').
Here's what I've tried so far:
select f.fid, f.fname
from faculty f
join course c
on f.fid = c.fid
join enroll e
on c.cid = e.cid
join student s
on e.sid = s.sid
where s.sid = ALL
(select sid
from student
where major = 'CSC');
select f.fid, f.fname
from faculty f
join course c
on f.fid = c.fid
join enroll e
on c.cid = e.cid
join student s
on e.sid = s.sid
group by f.fid, s.sid
having s.sid = ALL
(select sid
from student
where major = 'CSC'));
The logical hurdle I'm having a hard time understanding is how to make sure that the faculty member is teaching ALL of the current CSC majors. You can see that I've tried to add some logic to check each record returned, but I'm afraid I may be misunderstanding the syntax. These queries will run, but they return empty sets. Thanks for the help.
I agree the question may be unclear, and they might just be after all faculty that have taught any CSC major. However, just in case you still need all the faculty that have taught all CSC major, this should work:
The following query tells us the pairs of faculty and CSC majors:
select f.fid, s.sid
from faculty f
inner join course c
on f.fid = c.fid
inner join enroll e
on e.cid = c.cid
inner join student s
on e.sid = s.sid
where s.major = 'CSC'
group by f.fid, s.sid
Therefore, if we know the count of students who are computer science majors:
select count(1)
from student s
where s.major = 'CSC'
Then we can add up the number of CSC majors taught by each faculty member, and check it's equal to the total number of CSC majors:
select b.fid, b.fname
from (
select a.fid, a.fname, count(1) as taught_count
from (
select f.fid, f.fname, s.sid
from faculty f
inner join course c
on f.fid = c.fid
inner join enroll e
on e.cid = c.cid
inner join student s
on e.sid = s.sid
where s.major = 'CSC'
group by f.fid, s.sid
) a
group by a.fid, a.fname
) b
where b.taught_count = (
select count(1)
from student s
where s.major = 'CSC'
)
What you've done looks pretty good. I think you may just be over thinking it. This should logically give you what you're looking for:
Select f.fid, f.fname
from faculty f
join course c on c.fid = f.fid
join enroll e on e.cid = c.cid
join student s on s.sid = e.sid
Where major = 'CSC'
group by f.fid, f.fname
Try with
select f.fid, f.fname
from faculty f
join course c
on f.fid = c.fid
join enroll e
on c.cid = e.cid
join student s
on e.sid = s.sid
where s.sid IN (select sid from student where major = 'CSC');
Related
Schema:
This is what I'm thinking, but I don't think its right:
SELECT distinct t.teacherid, s.fname
FROM tea_cou t, students s, stu_cou c
WHERE t.courseid = c.courseid
You have to join the tables and then filter by teacher name.
SELECT S.*
FROM Teachers T
INNER JOIN Tea_Cou TC ON Tc.TeacherId = T.TeacherId
INNER JOIN Courses C ON C.CourseId= TC.CourseId
INNER JOIN Stu_Cou SC ON SC.CourseId = C.CourseId
INNER JOIN Students S ON S.StudentId = SC.StudentId
WHERE T.LNAME= 'name'
I have the tables like this(interconnected by Foreign Keys):
STUDENT:
SNUM, SNAME, FEES
FACULTY:
FID, FNAME
COURSE:
CNAME, TIME, FID
ENROLLED:
SNUM,CNAME
Requirement:
Update FEES of students by 15%, for whom Prof. Kavya is teaching.
I tried the following query, which is not working
UPDATE STUDENT SET FEES=FEES*1.15 WHERE SNUM IN
(
SELECT DISTINCT S.SNUM
FROM STUDENT S, COURSE C, ENROLLED E, FACULTY F
WHERE S.SNUM = E.SNUM AND E.CNAME = C.CNAME
AND C.FID = F.FID
AND F.FNAME = 'KAVYA'
);
Error: You can't specify target table STUDENT for update in FROM clause.
Kindly Help me to solve this problem
In MySQL You cannot update a table and select from the same table in a sub query which has been documented here. You can change the query into join instead of sub query as follows,
UPDATE STUDENT S
JOIN ENROLLED E ON S.SNUM = E.SNUM
JOIN COURSE C ON E.CNAME = C.CNAME
JOIN FACULTY F ON C.FID = F.FID
SET FEES=FEES*1.15
WHERE F.FNAME = 'KAVYA';
It is because in MySQL, you can't update the same table which you have used in the SELECT query. You can change it by joining them instead:
UPDATE STUDENT a
INNER JOIN
(
SELECT DISTINCT S.SNUM
FROM STUDENT S, COURSE C, ENROLLED E, FACULTY F
WHERE S.SNUM = E.SNUM AND E.CNAME = C.CNAME
AND C.FID = F.FID
AND F.FNAME = 'KAVYA'
) b ON a.SNUM = b.SNUM
SET a.FEES = a.FEES * 1.15
I have the following schema :
Department (dept_id, dept_name)
Student (student_id, student_name, major, level, age)
Professor (prof_id, prof_name, dept_id)
Class (name, meets_at, room, prof_id)
Enrolled (student_id, class_name, semester)
I need to Find the names of students with level SR who are enrolled in a class
taught by professor who works in department Computer Science.
based on my relational algebra understanding my attempt was
SELECT s.student_name FROM ( SELECT d.dept_id FROM department as d WHERE d.dept_name = 'computer science'
JOIN professor as p on d.dept_id = p.dept_id
JOIN class as c on p.prof_id = c.prof_id
JOIN enrolled as e on c.name = e.class_name
JOIN student as s on s.student_id = e.student_id )
WHERE s.level = 'sr' ;
but when i try it out i get sql syntax error.
Any help is much appreciated.
SELECT s.student_name
FROM department d
JOIN professor p on d.dept_id = p.dept_id
JOIN class c on p.prof_id = c.prof_id
JOIN enrolled e on c.name = e.class_name
JOIN student s on s.student_id = e.student_id
WHERE s.level = 'sr'
AND d.dept_name = 'computer science'
SELECT s.student_name FROM (you have to mention table name) where s.level = 'sr' ;
without table name it will show error.
I have a simple problem that's hard to describe (at least for me).
Consider the following schema for a database modeling courses:
COURSE (cid, did, name, num, creditHours),
STUDENT (sid, fname, lname, did)
ENROLLED_IN (eid, sid, cid)
What is a query that will find the sid of the students enrolled in course.name=Math" and "Science"?
I'm sorry i asked a similar (simpler) question thinking I could figure the rest out but I could not: https://stackoverflow.com/questions/18902489/how-to-find-entries-in-database-that-meet-multiple-matches
AS the other page suggests, you need to do two JOIN's to the same table. But since you want to use the Name and not the cid, you join to the COURSE based on the enrollment data.
SELECT DISTINCT s.sid
FROM STUDENT s
INNER JOIN ENROLLED_IN e ON e.sid = s.sid
INNER JOIN COURSE c ON c.cid = e.cid AND c.Name = 'Math'
INNER JOIN COURSE c2 ON c2.cid = e.cid AND c2.Name = 'Science'
If you need the whole student record, then...
SELECT STUDENT.*
FROM STUDENT
INNER JOIN
(SELECT DISTINCT s.sid
FROM STUDENT s
INNER JOIN ENROLLED_IN e ON e.sid = s.sid
INNER JOIN COURSE c ON c.cid = e.cid AND c.Name = 'Math'
INNER JOIN COURSE c2 ON c2.cid = e.cid AND c2.Name = 'Science'
) t0 ON t0.sid = STUDENT.sid
EDIT Instead of DISTINCT you could also use GROUP BY, ala
SELECT s.sid
FROM STUDENT s
INNER JOIN ENROLLED_IN e ON e.sid = s.sid
INNER JOIN COURSE c ON c.cid = e.cid AND c.Name = 'Math'
INNER JOIN COURSE c2 ON c2.cid = e.cid AND c2.Name = 'Science'
GROUP BY s.sid
EDIT and instead of using two joins, you can use HAVING clauses
SELECT s.sid
FROM STUDENT s
INNER JOIN ENROLLED_IN e ON e.sid = s.sid
INNER JOIN COURSE c ON c.cid = e.cid
WHERE c.Name IN ('Math', 'Science')
GROUP BY s.sid
HAVING COUNT(*) = 2
Table Student maps Student.student_name to Student.student_id
Table Course maps Course.course_name to Course.course_id
Table Enrollment maps Enrollment.student_id to Enrollment.course_id (I've heard this referred to as a join table.)
What is the SELECT statement that, given a student name, will return his list of course names? I think this may be some of it:
SELECT c.course_name FROM Course c
INNER JOIN Enrollment e ON c.course_id = e.course_id
...
WHERE s.student_name = 'Tom';
Beyond that, I'm clueless.
(This isn't homework, it's just a simplification of a work problem.)
SELECT c.course_name FROM Enrollment e
INNER JOIN Course c ON c.course_id = e.course_id
INNER JOIN Student s ON s.student_id = e.student_id
WHERE s.student_name = 'Tom';
also
SELECT c.course_name
FROM Enrollment e, Course c, Student s
WHERE c.course_id = e.course_id
AND s.student_id = e.student_id
AND s.student_name = 'Tom';