INNER JOIN to more than one table - sql

I have four tables
student
-------
id, int
firstName, varchar
lastName, varchar
course
------
id, int
name, varchar
semester
--------
id, int
name, varchar
mark
----
studentId, int
courseId, int
semesterId, int
mark, int
I want to make a sql query that retrives firstName, lastName, courseName, semesterName and mark for every row in the mark table.
I tried to do it with INNER JOIN but I can't make INNER JOIN for more than one table.
That code I reached finally
select student.firstName, student.lastName, course.name, semester.name, mark.mark
from mark
INNER JOIN student ON student.id = mark.studentId
INNER JOIN course ON course.id = mark.courseId
INNER JOIN semester ON semester.id = mark.semesterId

In Ms Access you have to include parentheses in a query with multiple joins:
select st.firstName, st.lastName, c.name, sm.name, m.mark
from (((mark m
INNER JOIN student st ON st.id = m.studentId)
INNER JOIN course c ON c.id = m.courseId)
INNER JOIN semester sm ON sm.id = m.semesterId)

Try theta style join:
select student.firstName, student.lastName, course.name, semester.name, mark.mark
from mark, student ,course, semester
WHERE student.id = mark.studentId AND course.id = mark.courseId AND semester.id = mark.semesterId

Related

How to extract rows from three tables

I know to ask this question is not appropriate.
Student table - ID, Name, GPA
Class table - ID, Title, Semester
Student_Class table - Student_ID, Class_ID, Student_Grade
From this table structure, how to extract the student name who attended class.title = ‘MATH101’ and class.semester = ‘FALL2018’.
Without much research I got to ask this question. How can I make a start on this?
Student_Class is join table which implements many-to-many relationship between Student and Class. So it just needed to join Student_Class with Student on student_id and Student_Class with Class on class_id.
select s.name
from Student s inner join Student_Class cs on s.id = cs.student_id
inner join Class c on cs.class_id = c.id
where c.title = ‘MATH101’ and c.semester = ‘FALL2018’.
You want to select the student name, so select from the student table. You only want to consider students who attended math in fall 2018, so add a where clause limiting the students accordingly.
This can achieved in various ways. One way to do this is
select name
from students
where id in
(
select student_id
from student_class
where class_id =
(
select id
from class
where title = 'MATH101'
and semester = 'FALL2018'
)
)
order by name;
Another is
select name
from students s
where exists
(
select null
from student_class sc
join class c on c.id = sc.class_id
where sc.student_id = s.id
and c.title = 'MATH101'
and c.semester = 'FALL2018'
)
order by name;

SQL Find student names according to grade

I am trying to print student names for each student that has more than one "2" grade. Grade is integer from CLASSSTUDENT table. Oracle database.
Code so far:
SELECT DISTINCT FIRSTNAME, LASTNAME
FROM PERSON
JOIN STUDENT ON PERSON.PERSONID = STUDENT.STUDENTID
JOIN CLASSSTUDENT ON STUDENT.STUDENTID = CLASSSTUDENT.STUDENTID
WHERE FINALGRADE = 2;
This get students having grade of "2". How must I change query to get students with more than one "2" grade?
SELECT FirstName, LastName
FROM Person p
INNER JOIN Student s ON p.PersonID = s.StudentID
INNER JOIN (
SELECT StudentID
FROM ClassStudent
WHERE FinalGrade = 2
GROUP BY StudentID
HAVING COUNT(*) > 1
) f ON f.StudentID = s.StudentID
or more simply:
SELECT FirstName, LastName
FROM Person p
INNER JOIN ClassStudent cs ON cs.StudentID = p.PersonID
WHERE cs.FinalGrade = 2
GROUP BY cs.StudentID, FirstName, LastName
HAVING COUNT(*) > 1
Though I prefer the former for reasons I don't myself fully understand (possibly something to do with only grouping on the primary key, or only using the group to filter the records... but really it just "feels" more right somehow).
I believe it would be something like:
SELECT FIRSTNAME, LASTNAME, COUNT(*)
FROM PERSON
JOIN STUDENT ON PERSON.PERSONID = STUDENT.STUDENTID
JOIN CLASSSTUDENT ON STUDENT.STUDENTID = CLASSSTUDENT.STUDENTID
WHERE FINALGRADE = 2
GROUP BY FIRSTNAME, LASTNAME
HAVING COUNT(*) >= 2;

SQL query find records that not persists in other tables

I need to print all persons which are not students and not teachers. I have three tables. Oracle database. Code so far:
SELECT PersonID, FirstName, LastName, Gender, DateOfBirth
FROM PERSON
INNER JOIN STUDENT S ON PERSON.PersonID = S.StudentID
INNER JOIN TEACHER T ON PERSON.PersonID = T.TeacherID
WHERE PERSON.PersonID != S.StudentID
AND PERSON.PersonID != T.TeacherID;
I guess my query is wrong because it returns 0 results. Do you have any idea what must I change?
" my query is wrong because it returns 0 results"
Inner joins return records when there is a match. You're trying to find PERSON records which join to neither STUDENT nor TEACHER. So, change your query to use outer joins:
SELECT PersonID, FirstName, LastName, Gender, DateOfBirth
FROM PERSON
LEFT OUTER JOIN STUDENT S ON PERSON.PersonID = S.StudentID
LEFT OUTER JOIN TEACHER T ON PERSON.PersonID = T.TeacherID
WHERE S.StudentID is null
AND T.TeacherID is null;
This is an anti-join: it returns records from PERSON which don't match records in STUDENT and TEACHER.
Use not exists:
select p.*
from person p
where not exists (select 1 from teacher t where t.teacherid = p.personid) and
not exists (select 1 from students s where s.studentid = p.personid);
Although you can write this query with left join, I think the version using not exists is almost a direct translation of the question, making it easier to understand.
In Oracle, you can also write this using minus -- if you want only the id:
select personid
from person
minus
select teacherid
from teacher
minus
select studentid
from student;
--Try this with Left Outer Join...
SELECT
P.PersonID,
P.FirstName,
P.LastName,
P.Gender,
P.DateOfBirth
FROM PERSON P
LEFT OUTER JOIN STUDENT S ON P.PersonID = S.StudentID
LEFT OUTER JOIN TEACHER T ON P.PersonID = T.TeacherID
WHERE S.PersonID is null and T.PersonID is null

SQL - listing members on enrolled classes

I am trying to figure out why this isn't working. I am trying to select each member's names and the classes that each member is enrolled on together with the class trainers name.
This is what I have at the minute:
SELECT
firstName, lastName, className, trainerName
FROM
member, _class, trainer, enrolment
WHERE
enrolment.memberID = member.memberID
AND enrolment.classID = _class.classID;
Any help or tips would be appreciated as I am still learning SQL.
Extra info:
enrolment table has columns entrolmentID, memberID and classID
trainer table has columns trainerID and trainerName
member table has memberID, firstName, lastName, age, trainerID
class table has classID, className, _day and trainerID
The valid syntax for a JOIN statement is:
SELECT FIELD1
,...FIELDN
FROM TABLE1 T1
INNER JOIN TABLE2 T2 ON T1.FIELDX = T2.FIELDY
So in your case, use:
SELECT firstName
,lastName
,className
,trainerName
FROM member
INNER JOIN enrolment ON enrolment.memberID = member.memberID
INNER JOIN _class ON enrolment.classID = _class.classID
INNER JOIN trainer ON trainer.trainerID = member.trainerID
Try this
SELECT firstname, lastname, classname, trainerName
FROM member
INNER JOIN enrollment
ON enrolment.memberID = member.memberID
INNER JOIN _class
ON enrollment.classID = class.classID
INNER JOIN trainer
ON trainer.trainerID = member.trainerID

How to get common category among columns in SQL

Consider the following schema for SQL:
Student (StudID, StudName, DeptID, Age, Gpa);
Course (CourseID, CourseName, InstructorID);
Department (DeptID, DeptName, Location);
Instructor (InstructorID, InstructorName, DeptID);
Section (SectionID, SectionName, Time, RoomID, CourseID, InstructorID);
Room (RoomID, RoomName, Location);
Enrolled (StudID, SectionID);
Q: How to find the names of all sections that either meet in common room or have five or more students enrolled?
Well I am not sure if it will work:)
Common names;
select st.StudName as names from Student as st inner join Departmant as d
on st.DeptID = d.DeptID inner join Instructor as i
on i.DeptID = d.DeptID inner join Course as c
on c.InstructorID = i.InstructorID inner join Section as s
on s.InstructorID = i.InstructorID inner join Room as r
on r.RoomID = s.RoomID inner join Enrolled as e
on e.StudID = st.StudID;
More than 5 student enrolled(Something experimental:);
select st.StudName as names from Student as st inner join Departmant as d
on st.DeptID = d.DeptID inner join Instructor as i
on i.DeptID = d.DeptID inner join Course as c
on c.InstructorID = i.InstructorID inner join Section as s
on s.InstructorID = i.InstructorID inner join Room as r
on r.RoomID = s.RoomID inner join Enrolled as e
on e.StudID = st.StudID where count(e.StudID = st.StudID)>4;
If you are using SQL-Server you can write the query like this(I didn't tested it. So I can't say it works 100% but I hope it gives you an idea):
SELECT SectionName
FROM Section
WHERE SectionID IN --Students in common room.
(
SELECT SectionID FROM Section
INNER JOIN Instructor ON Section.SectionID = Instructor.InstructorID --Section to which the Instructor belongs
INNER JOIN Department ON Department.DeptID = Instructor.DeptID --Department to which the Instructor belongs
INNER JOIN Room ON Room.Location = Department.Location --Room to which the Department belongs
)
OR --Student Enrollment greater than 5.
(
(SELECT COUNT(StudID) FROM Student
INNER JOIN Enrolled ON Student.StudID = Enrolled.StudID
INNER JOIN Section ON Section.SectionID = Enrolled.SectionID) >= 5
)
Q:6. Find the names of all sections that either meet in room New-8 or have five or more students enrolled.
Answer:
select sectionName
from student as S, Enrolled as E, Section as Se
where S.studId=E.studId AND E.sectionID=se.SectionID
group by sectionName
having count(*)>=3
UNION
SELECT sectionName
FROM SECTION S, ROOM R
WHERE S.RoomID=R.ROOMID AND R.RoomName='new2'
this is the correct query i have run it on Db