SQL, select from two tables based on a third, which references them - mysql

Just starting with SQL and the first all-nighter is already here.
I have three tables:
student (student_id, first_name, last_name)
course (course_id, name)
exam (ref_to_student_id, ref_to_course_id, score)
How do I make a select statement and list out student name, last name and course name, for all cases where achieved exam score was > X ?
This is my best shot:
SELECT last_name FROM student WHERE student_id IN
(SELECT ref_to_student_id FROM exam WHERE score > 50)
UNION ALL
SELECT name FROM course WHERE course_id IN
(SELECT ref_to_course_id FROM exam WHERE score > 50)
It's faulty, because I get:
last_name
last_name
name
name
name
and there's no way of telling exactly which student scored above X on which exam/course.
In my mind, something like this:
SELECT first_name, last_name, name
FROM student, course
WHERE student_id, course_id
IN (SELECT ref_to_student_id, ref_to_course_id FROM exam WHERE score > 50)
would produce something like this:
John Doe Chemistry
Jane Dove English
...
But, it only produces a notification about an error in the syntax.

You can use inner join between tables like this:
SELECT s.first_name AS first_name, s.last_name AS last_name, c.name AS course_name
FROM student s
INNER JOIN exam e ON e.ref_to_student_id = s.student_id
INNER JOIN course ON c.course_id = e.ref_to_course_id
WHERE e.score > 50;

You need to join these tables, not union them:
SELECT last_name, first_name, name, score
FROM student s
JOIN exam e ON s.student_id = e.ref_to_student_id
JOIN course c ON e.red_to_course_id = c.course_id
WHERE score > 50

Friend, try this:
SELECT s.first_name, s.last_name, c.name
FROM exam e
JOIN student s ON s.student_id = e.ref_to_student_id
JOIN course c ON c.course_id = e.ref_to_course_id
WHERE e.score > 50
I hope to help you!

Related

need SQL help, Find names of all departments whose professors collectively teach less than 3 courses

Tables:
department (dept_id, dept_name)
student (student_id, student_name, major, level, age)
professor (prof_id, prof_name, dept_id)
course (course_code, name)
semester_course (course_code, quarter, year, prof_id)
enrolled (student_id, course_code, quarter, year, enrolled_at)
the question is Find names of all departments whose professors collectively teach less than
3 courses
my query right now looks like
select d.dept_name,d.dept_id FROM department as d
WHERE d.dept_id in (
select d1.dept_id from department d1,professor p1
where p1.dept_id = d1.dept_id AND p1.prof_id IN (
select p2.prof_id from professor p2,semester_course sc
WHERE sc.prof_id = p2.prof_id GROUP BY sc.course_code having count(*) < 3
) );
and it brings back wrong results, any help?
You should join all three tables, department, professor, and semester_course. Since the question asks about the count of courses per department, you should use GROUP BY d.dept_id and COUNT(DISTINCT sc.course_code) to implement the criteria that they want.
SELECT d.dept_name
FROM department as d
JOIN professor AS p ON p.dept_id = d.dept_id
JOIN semester_course AS sc ON sc.prof_id = p.prof_id
GROUP BY d.dept_id
HAVING COUNT(DISTINCT sc.course_code) < 3

finding the student and teacher with the most courses in common

I need to find which teacher and student have the most overlapping courses (if any) using a MySQL script. I have built my own DB with the following tables:
Students (id, first name, last name)
Professors (id, first name, last name)
Courses (id, name)
Grades (student id, course id, assignment, grade)
Thought Process:
I need to list the students, teachers and courses:
select distinct students.first_name, professors.first_name, course_name from grades
join students on grades.student_id = students.student_id
join courses on grades.course_id = courses.course_id
join professors on courses.professor_id = professors.professor_id
Now I need to look through the information to find which student is taking multiple courses from the same professor. I just don't know how to implement that in MySQL.
Using your query as a base to start, you can group by student and professor to get the number of common courses.
The below query returns the students and professors that have the most common courses:
with cte as (
select
#I had to alias these column names to avoid a duplicate column name error (Quito)
students.first_name, students.last_name,
professors.first_name, professors.last_name,
count(distinct courses.id) counter
from grades
join students on grades.student_id = students.student_id
join courses on grades.course_id = courses.course_id
join professors on courses.professor_id = professors.professor_id
group by
students.first_name, students.last_name,
professors.first_name, professors.last_name
)
select * from cte
where cte.counter = (
select max(counter) from cte
)

Get all data from a table that contains two foreign key data

Table instructor: ID, name, dept_name, salary
Table student: ID, name, dept_name, tot_cred
Table advisor: s_ID, i_ID which contains student id and instructor id for the two table.
I need to find all the instructor and student's name where the department of the advisor is CComp.Sci
I can find all the id of the instructor and student whrer the intructor is fom Computer science. And only the name of the students.
But can't figure out both the name at the same time.
I wrote this:
SELECT student.name
FROM student
WHERE student.ID in (SELECT advisor.s_ID
FROM advisor
, instructor
WHERE advisor.i_ID = instructor.ID
and instructor.dept_name = 'Comp.Sci')
The root solution I think you need here is just a simple join between the three tables. But since you need a single list of both student and instructor names, this complicates things. One option is to union together a query which finds the matching students along with a query which finds the matching instructors.
SELECT s.name, 'student' AS type
FROM student s
INNER JOIN advisor a
ON s.ID = a.s_ID
INNER JOIN instructor i
ON a.i_ID = i.ID
WHERE i.dept_name = 'CComp.Sci'
UNION ALL
SELECT DISTINCT i.name, 'instructor'
FROM student s
INNER JOIN advisor a
ON s.ID = a.s_ID
INNER JOIN instructor i
ON a.i_ID = i.ID
WHERE i.dept_name = 'CComp.Sci'
Using "where .. in (..)" will give you bad performance, also it will not allow you to get the data from the table in the where clause.
Here is a solution if you mean to get the result of instructor name side alone with student name.
SELECT S.name AS Student,I.name AS Instructor
FROM Students AS S
JOIN Advisor AS A ON A.s_ID = S.Id
JOIN Instructor AS I ON I.Id = A.i_ID
WHERE I.dept_name = 'Comp.Sci'
*notice that I used alias
** if you want for example to get all students even those who lack instructor use LEFT JOIN

how to get data from other table?

List the name of students who enroll in both course ‘CS-204’ and course ‘CS-102’
table1:enroll
student id , code, grade
table2:student
student id ,name ,bdate,address
..................................
i try as
select student.name,enrol.code from student,enrol where code='CS-204' or code='CS-102'
You have to join both tables:
select student.name,enrol.code
from student join enrol on student.student_id=enrol.student_id
where code='CS-204' and student.student_id in (
select student.name,enrol.code
from student join enrol on student.student_id=enrol.student_id
where code='CS-102'
)
You need to join the tables
SELECT s.name, e.code
FROM student s
INNER JOIN enroll e ON s.student_id = e.student_id
WHERE e.code='CS-204' OR e.code='CS-102'
You need to add one more parameter to WHERE clause:
SELECT student.name, enroll.code
FROM student, enroll
WHERE (student.student_id=enroll.student_id) AND (enroll.code='CS-204' OR enroll.code='CS-102')
You can try doing this.
Select student.name from student join enroll
on student.student_id = enroll.student_id where
enroll.code in ('CS-204','CS-102');
You can also get the name of students from both courses this way:
SELECT b.name as student_name
FROM enroll a, student b
WHERE (a.student_id=b.student_id) AND (a.code='CS-204' or a.code='CS-102'`)

SQL count / query assistance

So I'm learning MySQL and I'm trying to do the following:
For each instructor list his / her name and the number of students he / she mentors.
The relevant part of the schema is:
Person(ID, Name)
Student(StudentID, MentorID)
Instructor(InstructorID)
Both InstructorID and StudentID map to Person.ID, and MentorID maps to InstructorID (Each student has an instructor mentor, and both instructors and students are Persons).
I've tried the following to no avail:
select p.Name, count(select s.StudentID
from Student s
where s.MentorID = i.InstructorID)
from Person p, Instructor i
where p.ID = i.InstructorID;
Also this after reading some things on StackOverflow:
select InstructorDetails.Name, count(Mentees)
from Instructor i
inner join Person as InstructorDetails
on InstructorDetails.ID = i.InstructorID
inner join Student as Mentees
on Mentees.MentorID = i.InstructorID;
Any suggestions?
You lack GROUP BY on your query,
SELECT InstructorDetails.Name, count(*) totalCount
FROM Instructor i
INNER JOIN Person as InstructorDetails
ON InstructorDetails.ID = i.InstructorID
INNER JOIN Student as Mentees
ON Mentees.MentorID = i.InstructorID
GROUP BY InstructorDetails.Name