multi-relation queries in SQL - sql

Given these four relations:
Mentorship (mentee_id, mentor_id)
Study (sid, credits)
Enrollment (did, sid)
Student (sid, street , city )
I want to write a query that finds all students who live in the same city and street as their mentor, assuming that all mentors and mentees are students.
I tried to write this query as:
SELECT sid
FROM Student, Mentorship
WHERE street IN (SELECT sid
FROM Student, Mentorship
WHERE mentor_sid = sid
AND ... )
It's incomplete but I tried to SELECT a sid from Student and Mentorship relations where street falls into a condition where mentor_sid and mentee_sid has same street and city.
I am new to SQL and still confused how to do these stuffs.

You need to join student (mentee) to student (mentor) via the link table
SELECT s1.* FROM Student s1
INNER JOIN Mentorship m ON s1.sid = m.mentee_id
INNER JOIN student s2 ON s2.sid = m.mentor_id
AND s2.street = s1.street AND s2.city = s1.city

Related

SQL query with more than 2 tables

I'm doing an exercise on ORACLE SQL.
Currently I got 3 tables.
Student values = "student_id ,name"
Subjects values = "subject_id, name"
Scores values = "score, student_id, subject_id"
I'm trying to retrieve the following information from my database.
Name of student, Name and id of the subject and finally the score that has the student_id "34560".
SELECT scores.score,
scores.subject_id,
student.name,
subject.subject_id,
subject.name
FROM scores
INNER JOIN students
ON scores.student_id = '34560'
INNER JOIN subject
ON /* and here's where i'm lost*/
Is there a way to put all together from the first part of the query where I call the list of students with student_id = "34560" and then query that list to see if it matches with the subject_id?
Use in operator for list of student id
SELECT sc.score, sc.subject_id,
st.name, sb.subject_id, sb.name
FROM scores sc
INNER JOIN students st
ON sc.student_id = st.student_id
INNER JOIN subject sb
ON sc.subject_id=sb.subject_id
where sc.student_id in ('34560','add_anotherstudentid','add_anotherstudentid') //you can add multiple student id

How to count the number of students taught by each teacher?

I have a database that has the following tables
Courses: CourseID*, CourseName, TeacherID
Teachers: TeacherID*, TeacherName
Students: StudentID*, StudentName
StudentCourses: CourseID*, StudentID*
Legend: * is the primary key.
How can I write to query that produces produces the number of students taught by each teacher?
For example
TeacherName, Count
Bob 15
Sarah 5
Zubair 1
Edit
select "TeacherName", count(*)
from courses inner join teachers on courses."TeacherID" = teachers."TeacherI"
join sutdentcourses on sutdentcourses."CourseID" = courses."CourseID"
group by "TeacherName"
order by "TeacherName";
You need make JOIN between the tables Teachers, Courses and StudentCourses, Group your records by TeacherName and Count the StudentID.
SELECT TeacherName, COUNT(StudentID)
FROM Teachers JOIN Courses USING(TeacherID)
JOIN StudentCourses USING(CourseID)
GROUP BY TeacherName

Filtering joins with conditions

I have 3 table, named as
students (id, name)
subjects (id, name, is_published)
student_subjects (id, student_id, subject_id)
The subjects taken by a student goes in student_subjects. But there are cases where student_subjects contains NULL subject_id for a student
Here's the data for Students table
1;"John"
2;"Ahmeah"
3;"Dina"
4;"Leo"
5;"Lenon"
Subjects Table
1;"Computer Sci";1
2;"Physics";1
3;"Bio";1
4;"Maths";0
Student_subjects
1;1;1
2;1;2
3;1;4
4;2;1
5;2;3
6;2;4
7;3;2
8;4;1
9;5;NULL
Currently to fetch all the students with their subjects and also display the name of the student who has no subject attached to him, I am using the query as follows
SELECT
students.*,
inners.name
FROM
students
LEFT JOIN ( SELECT
student_id,
subjects.name
FROM
student_subjects
JOIN subjects ON ( student_subjects.subject_id = subjects.id AND subjects.is_published = 1)
) AS inners ON (inners.student_id = students.id )
Is there a better way to do the same http://sqlfiddle.com/#!12/9cf93/12
SELECT s.*, su.name AS SubjName
FROM students AS s
LEFT JOIN student_subjects AS ss ON ss.student_id = s.id
LEFT JOIN subjects AS su ON su.id = ss.subject_id
Does the same thing as the one you listed. Is that what you are after?

How to find classmates of student C who are taking any of the classes that C is taking, in SQL?

There are two tables, students and courses. The students table has name, age and ssn.
Courses has ssn and Course.
Now the ssn in the courses table is NOT unique but the one in students is primary key.
I need to find out the students who are taking any of the classes that student C is taking (including C's name as well in the resulting solution).
It's a challenge problem so I can just not mind it but I want to find out what the solution is.
So far I've tried to use a union operator like this :
SELECT ssn
FROM courses
UNION SELECT ssn
FROM students
WHERE name = 'c'
All this does is it returns all the ssns from the table courses. The question asks us to effectively find the set UNION of the both tables to determine the solution.
Any help is appreciated!
SELECT DISTINCT s2.ssn, s2.name
FROM students s1
INNER JOIN courses c1 /* Find all courses taken by student 'c' */
ON s1.ssn = c1.ssn
INNER JOIN courses c2 /* Find all students in all of c's courses */
ON c1.course = c2.course
INNER JOIN students s2 /* Get the details for each of those students */
ON c2.ssn = s2.ssn
WHERE s1.name = 'c'
select distinct c1.ssn, s1.name from courses c1 // find distinct ssn and name for courses X (defined below)
inner join students s1 on c1.ssn=s1.ssn
where c1.course in
(select course
from courses // use to find all courses (say X) for student c
where ssn =
(select ssn from students where name='c')) // find ssn of student
Hope this helps

Selecting rows from a table that have the same value for one field

I have a MySQL database with these two tables:
Tutor(tutorId, initials, lastName, email, phone, office)
Student(studentId, initials, lastName, email, tutorId)
What is the query to return the initials and last names of any student who share the same tutor?
I tried SELECT intials, lastName FROM Student WHERE tutorId = tutorId but that just returns the names of all students.
You'll have to join students against itself:
SELECT s1.initials, s1.lastName
FROM Student s1, Student s2
WHERE s1.studentId <> s2.studentID /* Every student has the same tutor as himself */
AND s1.tutorId = s2.tutorid
If you want to output the pairs:
SELECT s1.initials, s1.lastName, s2.initials, s2.lastName
FROM Student s1, Student s2
WHERE s1.studentId <> s2.studentID /* Every student has the same tutor as himself */
AND s1.tutorId = s2.tutorid
To get a list of Tutor - Students:
SELECT tutorId, GROUP_CONCAT( initials, lastName SEPARATOR ', ')
FROM `Student`
GROUP BY tutorId
/* to only show tutors that have more than 1 student: */
/* HAVING COUNT(studentid) > 1 */
SELECT Tutor.tutorId, Student.initials, Student.lastName FROM Student INNER JOIN Tutor ON Tutor.tutorId = Student.tutorId GROUP BY tutorId
This will return (not tested, but it should) a list of student initials and last names grouped by tutorId. Is that what you want?
Join Student table to itself
SELECT S1.intials, S1.lastName
FROM Student S1, Student S2
WHERE S1.tutorId = S2.tutorId
AND S1.studentId <> S2.studentId
this is the query in SQL Server, im sure the idea is very close to mySql:
select s1.initials,s1.lastname,s2.initials,s2.lastname from students s1 inner join students s2 on s1.tutorid= s2.tutorid and s1.studentid <> s2.studentid
You will have to make a query for every single tutorId. Pseudo-Code:
for id in tutorIds
query('SELECT intials, lastName FROM Student WHERE tutorId = '+id )
If you wanna have a list containing all Tutors who actually have students, do a
SELECT tutorId FROM Student GROUP BY tutorId