Schema:
Student(studentid,name,age)
Course(coursename,dept)
enroll(studentid,coursename,grade)
I need to write sql to find student names for each age group with the maximum grade for the courses taken from the history and political science department.
My attempt so far has been
SELECT
name
FROM
student
GROUP BY age
HAVING sid IN
(
SELECT
max(grade)
FROM
enroll e,enroll e1
WHERE
e.studentid = e1.studentid
AND e.coursename = (
SELECT coursename FROM course
WHERE
dname like '%History%'
)
AND e1.coursename = (
SELECT coursename FROM course
WHERE
dname like '%PoliticalScience%'
)
)
You can get the top grade using subquery. Try,
SELECT d.*,
f.dept,
e.grade
FROM student d
INNER JOIN enroll e
on d.studentID = e.studentID
INNER JOIN course f
ON e.courseName = f.courseName
INNER JOIN
(
SELECT a.age, c.dept, Max(b.grade) maxGrade
FROM student a
INNER JOIN enroll b
on a.studentID = b.studentID
INNER JOIN course c
ON b.courseName = c.courseName
WHERE c.dept IN ('history','political science')
GROUP BY a.age, c.dept
) topScore
ON topscore.age = d.age AND
topscore.dept = f.dept AND
topscore.maxGrade = e.grade
You can try something along these lines
select
s.name
from
student s, enroll e,
(
select
s.age as age, e.coursename as coursename, max(e.grade) as grade
from
student s, course c, enroll e
where
s.studentid = e.studentid
and c.coursename = e.coursename
and (c.dept = 'history' or c.dept = 'political science')
group by s.age, e.coursename
) t
where
s.studentid = e.studentid
and s.age = t.age
and e.grade = t.grade
and e.coursename = t.coursename
Related
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 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');
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
I have two tables; One that contains students names and sids and the other is a "take" table containing the sids of students and their grades.
I want to show the names of students who have average greater than that of a student name "Peter-Parker".
I have tried the query below, but it doesn't work.
SELECT s.sid, s.fname, s.lname
FROM student s, take t
WHERE s.sid = t.sid AND AVG(t.grade) > ALL(
SELECT AVG(grade)
FROM take, student
WHERE student.fname = 'Ali' and student.lname='Demir');
WITH AliAv(avg) AS
(SELECT AVG(grade) from take t, student s
where t.sid = s.sid ands.fname = 'Ali' and s.lname = 'Demir')
select student.sid, student.fname, student.lname
from student, take
where student.sid = take.sid Group by student.sid
having avg(take.grade) > AliAv.av;
SELECT s.sid, s.fname, s.lname, AVG(t.grade) AS average
FROM student AS s
JOIN take AS t ON t.sid = s.sid
GROUP BY s.sid
HAVING average > (
SELECT AVG(t2.grade)
FROM student AS s2
JOIN take AS t2 ON t2.sid = s2.sid
WHERE s2.fname = 'Peter' and s2.lname = 'Parker'
)
This works in SQL Server, I don't know if the syntax is valid in MySQL:
SELECT *
FROM Student s
WHERE
(SELECT AVG(Grade) FROM Take WHERE SID=s.ID) > (SELECT AVG(Grade) FROM Take WHERE SID = (SELECT SID FROM Student WHERE FName='Peter' AND LName='Parker'))