mysql - three joins on the same table - sql

I have two tables:
persons
- person_id
- fullname
students
- student_id
_ person_id
- father_id
- mother_id
In students table the last three columns store ids from persons table. What SELECT could retrieve the following data:
- student name
- father name
- mother name
We assume no WHERE, ORDER BY, or LIMIT for simplicity

try this:
select sp.fullname studentname, fp.fullname fathername, mp.fullname mothername
from students s
inner join persons sp on (s.student_id = sp.person_id)
inner join persons fp on (s.father_id = fp.person_id)
inner join persons mp on (s.mother_id = mp.person_id)

Try below query -
SELECT p.fullname,m.fullname,f.fullname from students s
LEFT JOIN persons p ON s.person_id = p.id
LEFT JOIN mother m ON s.mother_id = m.id
LEFT JOIN father f ON s.father_id = f.id
WHERE s.student_id = 'id of which student record you want';

Related

How to display Mother and Father of a person separately from same table in psql

Person table
PersonParent table(relation)
How to display all the records of person table, with their parents, whether or not having parents?
Output
that would be :
here is how to join to get the parents information alongside with person info , however this way , the person row will repeat for each parent :
select p.*, concat_ws(',',parent.firstname , parent_lastname) as ParentName
from persons p
cross join (select *
left join PersonParent pp
on p.personId = pp.personId
left join persons parent
on pp.parentId = parent.personid
if you want to show only one row per person, you can use query below, I used gender column to distinguish between mother and father:
select * from persons p
left join lateral(
select max(concat_ws(',', parents.firstname, parents.lastname)) filter (where parents.gender = 'm') as fatherrname
, max(concat_ws(',', parents.firstname, parents.lastname)) filter (where parents.gender = 'f') as mothername
from personparents pp
join persons parents on pp.parentid = parents.id
where pp.personid = p.id
group by pp.personid
) pp on true

Sql select clause with three table

I am trying to write a sql query to show student list for each course.
The diagram below show the database relationship.
The SQL query I have written is:
select * from Courses
inner join Enrollments on Enrollments.CourseId = Courses.CourseId
inner join Student on Enrollments.StudentId = StudentId
where Courses.CourseId = 1
The issue is that i am getting returned alot more data than I expected as only one student is registered for the course but i get ten entries. I am not sure if i have done somethings fundamental wrong or is my query the issue.
This is the data
This is the result
I expected only two rows to be returned.
Thanks
Every column in your query must be qualified with the table's name.
You did not qualify the column StudentId in this join:
inner join Student on Enrollments.StudentId = StudentId
If you did you would find the error which is that there is no column StudentId in the table Student and you should use the column Id:
select * from Courses
inner join Enrollments on Enrollments.CourseId = Courses.CourseId
inner join Student on Enrollments.StudentId = Student.Id
where Courses.CourseId = 1
or better with aliases for the tables:
select *
from Courses as c
inner join Enrollments as e on e.CourseId = c.CourseId
inner join Student as s on e.StudentId = s.Id
where c.CourseId = 1
The primary key of table Student is Id, not StudentId.
So the correct query is:
select * from Courses
inner join Enrollments on Enrollments.CourseId = Courses.CourseId
inner join Student on Enrollments.StudentId = Student.Id
where Courses.CourseId = 1

Select the records where ID is in different table

I have 3 tables. Below is the structure:
Student : SID,SNAME
Subject : SUID,SUNAME
Rid : SID,SUID
the result of the query should be :
SNAME SUNAME
Try this:
select st.SNAME
, sj.SUNAME
from Rid r
inner join Student st on r.SID = st.SID
inner join Subject sj on r.SUID = sj.SUID
Use this one:
select st.SNAME, sj.SUNAME
from Rid r
left join Student st on r.SID = st.SID
left join Subject sj on r.SUID = j.SUID
You have two tables and a relationship table. The relationship (Rid) table is the one that relates the other two (Student and Subject). You must search the Rid records where the Student and the Subject are joined:
SELECT s.sname, sb.suname
FROM student s, subject sb, rid r
WHERE s.sid = r.sid AND sb.suid = r.suid;
or with New Style
SELECT s.SNAME, sb.SUNAME
FROM Rid r
INNER JOIN Student s on r.SID = s.SID
INNER JOIN Subject sb on r.SUID = sb.SUID

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

Return column name where Join condition is null

I have 2 tables: Employee and Person with the structure
Employee: Id, PersonId, Designation, IsActive
Person:Id, Name, Contact
Employee's PersonId column references Person's Id and can be null
I need to return an employee's Name and my join criteria is
SELECT emp.Salary, emp.Designation, emp.IsActive, p.Name from Employee emp
JOIN Person P ON P.Id = emp.PersonId or (p.Id is NULL AND emp.Id IS NULL)
This is incorrect as my requirement is:
If emp.PersonId = null, return p.Name = NULL
else return p.Name = Person's Name from table
Any pointers on this?
you need an outer join
SELECT emp.Salary, emp.Designation, emp.IsActive, p.Name
from Employee emp
left JOIN Person P
ON P.Id = emp.PersonId
when you use an INNER JOIN (or JOIN) you only select the rows matching the join critiria, in your example you would never nave a NULL Person name because if the Employee is not assiciated with a Person, that record would not be selected.
If you use OUTER JOIN (LEFT/RIGHT JOIN), ALL record from the main table (1st with LEFT and 2nd with RIGHT) will be selected.
Hope this helps.