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'))
Related
Select s.SID , s.Lastname, s.Firstname, s.MI, g.YearLevel, g.Course,
count(s.SID) As 'Number Of Passed Subject'
From student s
inner Join grades g on g.StudentID = s.SID
Where g.Completion = 'Passed' and g.YearLevel = '4th Year'
group by g.YearLevel, g.Course
order by g.YearLevel, g.Course;
Select s1.SID , s1.Lastname, s1.Firstname, s1.MI, g1.YearLevel, g1.Course,
SUM(su.LecUnit) As 'Total of Units Passed'
From grades g1
INNER Join student s1 ON s1.SID = g1.StudentID
INNER Join subjects su ON su.SubjectCode = g1.SubjectCode
WHERE g1.Completion = 'Passed' AND g1.YearLevel = '4th Year'
GROUP BY g1.Course, g1.YearLevel
order by g1.Course, g1.YearLevel;
Use the second query as the starting point, and then add a distinct count of student courses for the number of passed subjects. The logic here is that the additional join to the subjects table might duplicate each intermediate record from the first two joins. Taking the distinct count removes this possible duplication.
Select s1.SID, s1.Lastname, s1.Firstname, s1.MI,
COUNT(DISTINCT g1.Course) As `Number Of Passed Subject`,
SUM(su.LecUnit) As `Total of Units Passed`
FROM student s1
INNER JOIN grades g1 ON s1.SID = g1.StudentID
INNER JOIN subjects su ON su.SubjectCode = g1.SubjectCode
WHERE g1.Completion = 'Passed' AND g1.YearLevel = '4th Year'
GROUP BY 1
ORDER BY 1;
Note that I am also grouping only by s1.SID. Assuming SID be the primary key from that table, it covers all columns from the student table. The other table fields you were selecting probably don't belong there.
There are 3 tables
Students (sid:integer, sname:string, age:integer)
Courses (cid:integer, cname:integer, credits:integer)
Grades(sid:integer, cid:integer, grade:string)
i would like to get students who only take courses with 4 credits
I have tried
SELECT sname FROM Students JOIN Grades ON Student.sid = Grades.sid
JOIN Grades ON Course.cid = Grades.cid
WHERE credits = 4
You can join the tables, group by student and set the condition in the having clause:
SELECT s.sid, s.sname
FROM Students s
INNER JOIN Grades g ON g.sid = s.sid
INNER JOIN Courses c ON c.cid = g.cid
GROUP BY s.sid, s.sname
HAVING SUM(c.credits <> 4) = 0
I have the following 3 tables for students and I need to find the names of students who currently are enrolled in classes that meet at the same time
student(**snum**, sname, major, level, age)
class(**cname**, meets_at, room)
enroll(**snum**, **cname**)
The keys for each table is in bold.
I have tried the folling code and I'm not sure whether I'm close to the correct answer here.
select s.sname
from student s
join
( select c.cname
, c.meets_at
, (count(*)
from class c
having count( * ) > 1
) e
on c.cname = e.cname
and s.snum = e.snum;
I would think of this as joining on students with meetsat. So, this gets students with their class times:
select s.sname, c.meets_at
from students s join
enrolls e
on s.snum = e.snum join
classes c
on c.cname = e.cname;
Then, to get the duplicates, use aggregation and filter using having:
select s.snum, s.sname, c.meets_at, count(*) as cnt
from students s join
enrolls e
on s.snum = e.snum join
classes c
on c.cname = e.cname
group by s.snum, sname, c.meets_at
having count(*) >= 2;
Note that this includes the ids as well as the name, because two students could have the same name.
Finally, a student could have multiple pairs of classes that conflict, but you only want to see the student once. Although the above is probably sufficient for your purposes, a more accurate solution for the stated problem would be:
select distinct s.sname
from students s join
enrolls e
on s.snum = e.snum join
classes c
on c.cname = e.cname
group by s.snum, sname, c.meets_at
having count(*) >= 2;
select s.snum, s.sname, c.meets_at ,count(*) as cnt into #tempStudents
from students s
join enrolls e on s.snum = e.snum
join classes c on c.cname = e.cname;
Put the whole data in temporary table
select sname from #tempStudents
group by snum,sname ,meets_at
having cnt >=2
Now apply filtration on temporary table for getting desire data
and if u need distinct name of student put Distinct keyword before sname.
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
I am having trouble trying to create a query to:
Select all the students who have not completed all peer review's for a particular week.
background: Each week, every student must peer review their peers in the same group.
Each group can be a different size, which is the problem I am having.
this is my current test data:
Table 1: peer review table
Table 2: student table.
This is my inital query, groups all the students based on the amount of peer review's they've made. I now need to to check if the count(*) is less than the size of the group for each student :
SELECT *
FROM peerreview
RIGHT JOIN student
ON student. studentID = peerreview.reviewer
WHERE week = 11
GROUP BY studentID
HAVING Count(*) < ????
Following query will return the student which has reviewed all the students in same group.
SELECT a.reviewer,
a.groupid
FROM (SELECT student2.studentID AS reviewer,
student1.groupid,
Count(*) AS cnt
FROM student student1
INNER JOIN peerreview
ON student1.studentID = peerreview.reviewee
INNER JOIN STUDENT STUDENT2
ON student2.studentID = peerreview.reviewer
WHERE student2.groupid = student2.groupid
AND peerreview.week = 11
GROUP BY student1.groupid,
student2.studentID) a
INNER JOIN (SELECT groupid,
Count(*) - 1 AS cnt
FROM student
GROUP BY groupid) b
ON a.groupid = b.groupid
AND a.cnt = b.cnt
See SqlFiddle
Select S.StudentId As Reviewer
, S1.StudentId As StudentYetToBeReviewed
, Weeks.WeekNum
From Student As S
Join Student As S1
On S1.GroupId = S.GroupId
And S1.StudentId <> S.StudentId
Cross Join (
Select 7 As WeekNum
Union All Select 11
) As Weeks
Where Not Exists (
Select 1
From PeerReview As P1
Where P1.reviewee = S1.StudentId
And P1.Week = Weeks.WeekNum
)
Order By WeekNum, reviewer
This provides you a list, by week, of the reviewer and the person they need to review. In the real solution, you would want to replace the Cross Join of weeks with a distinct list of weeks in which reviews should happen.
SQL Fiddle version
select distinct s1.*
from student s1 inner join student s2 on s1.groupId = s2.groupeId
left join peerreview pr on pr.revieweer = s1.studentId
and pr.reviewee = s2.studentId
where pr.Week = ? and pr.revieweer is null and s1.studentId <> s2.studentId