How to retrieve students data based on teachers ID - sql

According to a simple scenario ER diagram as follows.
Based on that, I developed a database mapping as follows.
In there, orange color columns shows the primary key of the tables and yellow color columns shows foreign key of the tables. Is this mapping correct? Now my problem is I need to retrieve students data who learned from some teacher, which means need to retrieve some teacher's sudents who learned from his/her.

You need to learn about how to join tables using different types of available JOINs.
For your scenario , try like following, it will give you Student and the Teacher mapping.
select s.*
tbl_student s
inner join tbl_Course_Subjects tcs on s.Course_Id= tcs.Course_Id
inner join tbl_Subjects_Teacher tst on tst.SubjectId=tcs.Subject_Id
inner join tbl_Teacher t on t.Teacher_Id=tst.Teacher_Id
where t.Teacher_Id = #SomeTeacherId

Related

SQL Server - Question about Inheritance in Database Schemas

I'm having problems understanding the class table inheritance structure that you can implement using database tables. Info on class table inheritance. I have a use case where I have quite different types of persons that I need to model, but they have very minor differences. For example, all of these persons, like Student, Professor and so on, have a surname and a lastname. My first thought was to move theses attributes into a different table inside a base table like you would do in Object Oriented Programming. Here to illustrate further:
Right now, a Professor can only have one person, for example, otherwise it wouldn't make sense in my use case. Also, I have a school table that has two foreign keys, one for the Professor and one for the Student. Lets assume that a school can also have only one professor and one student. This is not the real use case that I have. This example just represents the relation in my real use case which would be too much to explain here.
What I don't understand is how you would collect data based on that. I'm trying to make a SQL Server View where I want to load the Person of the Professor and the Person of the Student from the view point of the School Table. For example:
SELECT
School.professor_id
surname,
lastname
FROM dbo.School AS school
INNER JOIN dbo.Professor as prof
ON school.professor_id = prof.ID
INNER JOIN dbo.Person as prof_person
ON prof.person_id = prof_person.ID
I can output the surname and lastname of the professor, but now I am stuck since I can't figure out how to get the person of the student.
A subtype table typically shares a key with the supertype table, instead of having its own PK and a FK. EG Student.ID is both the PK and the FK.
Then just join Student>Person in addition to Professor>Person, eg
SELECT
School.Id,
prof_person.surname prof_surname,
student_person.surname student_surname
FROM dbo.School AS school
INNER JOIN dbo.Professor as prof
ON school.professor_id = prof.ID
INNER JOIN dbo.Person as prof_person
ON prof.ID = prof_person.ID
INNER JOIN dbo.Student as student
ON school.student_id = student.ID
INNER JOIN dbo.Person as student_person
ON student.ID = student_person.ID
INNER JOIN is associative, so no need for special ordering or parentheses.

How to link tables correctly in SQL to add roles to staff?

Currently I have a staff table with columns:
Staff_Id, first_name, Surname.
My second table is:
Id, management_role.
When I link the tables each staff member gets added to every management role. So for example a person in first table called Jim is added three times as manager, supervisor, intern and this happens for every staff.
Some things to consider that are your ID columns are primary keys for their respective tables. If not are every value in the column is unique? Also are ids not
From your description you might be using a cross join here. The thing you need is inner join so it joins the matching id's together.
So you can do
SELECT *
FROM staff_table as st
INNER JOIN management_table as mt
ON st.Staff_Id = mt.ID

SQL query to pull data from three different tables

I have to create a SQL query to list all the Nurses in the ‘Sparrow’ Wing ordered by last name, first name.
However, I need to pull Nurse_name and Nurse_surname from the Nurse table, which is linked to another table called Sister by the foreign key Sister_ID, this table is then linked to another table called Wing which has the foreign key Sister_ID.
The nurse is managed by the sister and the sister manages the wing.
Can anyone help me with an SQL query for this? As it is, I am only able to get the data from nurse and sister tables.
Since you seem to be aware that you should use the inner join to connect tables (but apparently not that the connection needs to be via the related columns) you should apply that knowledge to connect all the tables you need to answer the query.
If you start at the end result and work your way backwards you first chose the columns you need:
select Nurse.Nurse_name, Nurse.Nurse_surname
and then as they belong to the Nurse table you use that as source in the from clause
from Nurse
to get the Wing you need to connect the Sister table, but to connect that and Nurse you first need the SisterNurse table joined on the shared attribute
join SisterNurse on Nurse.Nurse_ID = SisterNurse.Nurse_ID
now you can join Sister on the attribute shared with SisterNurse
join Sister on Sister.Sister_ID = SisterNurse.Sister_Id
and finally you can join Wing
join Wing on Wing.sister_ID = Sister.Sister_ID
limit the Wings to the one names 'Sparrow'
where Wing.Wing_Name = 'Sparrow'
and order the data
order by Nurse.Nurse_surname, Nurse.Nurse_name
Put it all together and you get:
select Nurse.Nurse_name, Nurse.Nurse_surname
from Nurse
join SisterNurse on Nurse.Nurse_ID = SisterNurse.Nurse_ID
join Sister on Sister.Sister_ID = SisterNurse.Sister_Id
join Wing on Wing.sister_ID = Sister.Sister_ID
where Wing.Wing_Name = 'Sparrow'
order by Nurse.Nurse_surname, Nurse.Nurse_name
You don't give much information about the schema involved but maybe this will help:
select
n.Nurse_name
, n.Nurse_surname
, w.Wing_name
, managing_nurse.Nurse_name
, managing_nurse.surname
from
Nurse n
join Sister s on n.Sister_ID=n.Sister_ID
join Wing w on s.Sister_ID=w.Sister_ID
join Nurse managing_nurse on w.Nurse_Manager_ID=managing_nurse.Sister_ID
A simple way is to use 'union':
select * from (
select nurse_name, nurse_surname, 'nurse' as nurse_type from nurse_table
union
select nurse_name, nurse_surname, 'sister' as nurse_type from syster join nurse_table on nurse_table.syster_id = syster.syster_id
union
select nurse_name, nurse_surname, 'wing' as nurse_type from wing join syster on wing.syster_id = syster.syster_id join nurse_table on nurse_table.syster_id = syster.syster_id )
order by nurse_surname, nurse_name
Hope this help you!
P.S.
I assume that syster and wing tables have nurse_name and nurse_surname fields.
If not you have to give the same alias to all the selected columns

writing sql query between tables

Which SQL query could I write to satisfiy this need:
"List the names of the students who take a course from instructor named John."
Not sure that you can, from the depicted relations.
You can identify tutors by selecting on InstructorID and filtering on Instructor.FirstName.
You can join that subset onto course, via the InstructorCourses Join Table - join InstructorID to that and join the result to Courses using CourseID
In this way, Instructor.InstructorID -> (InstructorCourses.InstructorID , InstructorCourses.CourseID ) -> Courses.CourseID.
This lets you find information about the courses taught by instructors filtered on their name.
You don't present any link between students and courses in your diagram. I suspect you're missing a relation StudentCourses, which ought to be similar to InstructorCourses, but rather links students to courses. With that data in the mix, you can extend the join to match students to the courses from the relationship you already have.
Your diagram implies a relation between Student and InstructorCourses, which seems incorrect - both because there is no key to join on, and also because the logical relationship would not be correct. I think this is probably an error.
It is impossible to satisfy the SQL query you need because your conception does not allow it in that there is no relationship between the 2 tables Student and InstructorCourses.

Inner Join Help - How to order table join?

I have 2 tables:
Class (PK = Tutor)
Columns: ID / Tutor / Room
Teacher (PK FK = Tutor)
Columns: Tutor / Contact
I want to join both tables.
Does it matter what order the tables are joined?
ie.
SELECT Class.ID, Class.Tutor, Teacher.Contact
FROM **Class INNER JOIN Teacher** ON Class.Tutor=Teacher.Tutor
or could I do it the other way round and Teacher INNER JOIN Class instead?
Both tables also share a common column name Tutor.
Does it matter if I use Class.Tutor or Teacher.Tutor in the query?
For an INNER JOIN, the order does not matter; the result set you will get will contain all the rows from both Class and Teacher where the common field Tutor matches, whichever order you specify Teacher and Class.
When you use an OUTER JOIN, the order does matter; I would recommend looking at the answers to What is the difference between Left, Right, Outer and Inner Joins?.
Yes, the order matters.
Selecting from class and joining Teacher will show only those classes that have a teacher
Selecting from teacher and joining Class will show only those teachers that have a class
Depending on what you are trying to achieve you'll know which is most relevant.
I'd recommend using "left join" though, it will give you all the classes even if they don't have teacher assigned etc
FWIW "class" is likely to be a reserved word in your database, server side script and client side scripting languages. I'd find another word for that table name.