finding the student and teacher with the most courses in common - mysql

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
)

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

Return all courses a student is taking (Many to Many SQL Database example)

I'm fairly new to MySQL, and trying to understand the many-to-many relationship since these examples can popup in interviews
There are 3 tables, and since a Student can have many courses and a Course can have many students, this is a Many-to-Many relationship right?
The tables are
Student- has student ID, name, date of birth, and department.
Courses- Has ID, Name of course
Student_Courses- Has student_id, course_id
How would I display these 2 questions-
1) Given a studentID, return all the names of the courses the student is taking
2) Return the name of students who is taking X amount of courses or more (Ex. 4 or more courses).
Im trying to write queries on these, but I'm stuck...
In the case of selecting all of the courses for a given student ID you could try the following, which will return one row for each Course a Student is associated with.
select
s.name as StudentName,
c.name as CourseName
from `Student` as s
inner join `Student_Course` as sc on (sc.student_id = s.ID)
inner join `Course` as c on (c.ID = sc.course_id)
where
(s.`ID` = 'given_Student_ID_here')
;
As for selecting a list of the names of Students taking N or more courses, for this you might use an aggregating sub-select as a WHERE clause in which we reference one of the outer tables (i.e. [Student]) so that the result of the aggregation is personalised per Student record:
select
s.name as StudentName
from `Student` as s
where
(
(
select count(*)
from `Student_Course` as sc
inner join `Course` as c on (c.ID = sc.course_id)
where (sc.student_id = s.ID)
) >= 4
)
;
You might also consider an alternative approach to this second problem by using the GROUP BY and HAVING clauses:
select
s.name as StudentName
from `Student` as s
inner join `Student_Course` as sc on (sc.student_id = s.ID)
inner join `Course` as c on (c.ID = sc.course_id)
group by
s.name
having
count(*) >= 4
;

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

Listing later dates in comparison to another entry in SQL

How would I list the students who started later than start year of student with id = 8871?
This is what I have so far:
SELECT sid s1
FROM Student
WHERE s1.started <= sid = '8871';
I went to this link for some reference but I'm still having issues:
Query comparing dates in SQL
Student Table has:
Student (Lastname, Firstname, SID, Started)
any help would be great
I'd use a self join where one side of the join contains the students you want and the the reference student 8871:
SELECT a.*
FROM student a
JOIN student b ON b.sid = '8871' AND a.started > b.started

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