SQL Server - Question about Inheritance in Database Schemas - sql

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.

Related

How to retrieve students data based on teachers ID

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

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.

SQL query that limits results based on appearance in other tables

I'm a SQL novice, but need to write some SQL statements for a Java program that has to interact with a database. Our Java textbook covers only very basic SQL commands, and I am having trouble getting a more advanced (by my standards) one to work.
Here's the situation:
The database has 5 tables.
Teacher: TeacherID (PK), LastName
Class: ClassID (PK), Description
Room: Building, Room Number, PK is the combo of those two
TeachingAssignments: TeacherID(FK), ClassID(FK)
ClassRoomAssignments: ClassID(FK), Building, Room Number(combo is FK)
I need to give just the LastName, ClassID, and Building of only those teachers, classes, and rooms that are fully assigned. I.e., if a class both has a teacher and a room assignment, then I need to give that class's ID, the assigned teacher's last name, and the assigned building.
I have little idea how to proceed.
I've been playing around with statements like the following but they aren't working for me:
SELECT Teacher.LastName, Class.ClassID, Room.Building
FROM Teacher, Class, Room, TeachingAssignments, ClassRoomAssignments
WHERE Teacher.TeacherID = TeachingAssignments.TeacherID
AND Room.Building = ClassRoomAssignments.Building
AND Class.ClassID = TeachingAssignments.ClassID
AND Class.ClassID = ClassRoomAssignments.ClassID
Can anyone help? Thanks!
Your problem is that you need to add the respective joins for your table.
instead of doing:
SELECT Teacher.LastName, Class.ClassID, Room.Building
FROM Teacher, Class, Room, TeachingAssignments, ClassRoomAssignments
WHERE Teacher.TeacherID = TeachingAssignments.TeacherID
AND Room.Building = ClassRoomAssignments.Building
AND Class.ClassID = TeachingAssignments.ClassID
AND Class.ClassID = ClassRoomAssignments.ClassID
you need something like that
SELECT Teacher.LastName, Class.ClassID, Room.Building
FROM
Teacher INNER JOIN TeachingAssignments
ON Teacher.TeacherID = TeachingAssignments.TeacherID
INNER JOIN Class
ON Class.ClassID = TeachingAssignments.ClassID
INNER JOIN ClassRoomAssignments
ON Class.ClassID = ClassRoomAssignments.ClassID
INNER JOIN Room
ON Room.Building = ClassRoomAssignments.Building
As you can see every INNER Join is followed by it respective ON clause which is in charge of designing which element is going to be joined.

MySQL multi table join query

Result needed: The registration number of the cars used by Instructors at the Glasgow, Bearsden office.
The 3 relevant tables I have are; ( I have omitted the non-relevant table information, to simplify this. The database is called easydrive.
No this is not a School or UNI assignment, it is a question from a text book, that we have been given to do so we can learn how to do it, no marks are awarded for this, so you are not doing my homework for me.
**++Staff++**
(PK) Staff ID
(FK) Address ID
(FK) Office
(FK) Car Allocation Number
First Name
Last Name
Position/Title
Office
**++CarAllocation++**
(PK) Car Allocation Number
(FK) Staff ID
(FK) Car ID
**++Car++**
(PK) Car ID
Car Rego
So I need to so a join I think and I think it needs to go something along these lines but am very confused.
SELECT car.rego
FROM car
WHERE staff.office=’Glasgow’ OR ‘Bearsden’
Can someone please fill in the blanks so I can learn how to perform this, do I need to make a new table?
You query most probably needs to look something like this:
SELECT first_name, last_name, car_rego
FROM staff
JOIN carallocation ON (carallocation.staff_id = staff.staff_id)
JOIN car ON (car.car_id = carallocation.car_id)
WHERE staff.office = 'Glasgow' OR staff.office = 'Bearsden';
Note that JOIN is a synonym for an INNER JOIN in MySQL.
I haven't tested it but this should help.
select car.rego
from car
inner join carrallocation ca on ca.carid = car.carid
inner join staff s on ca.staffid = s.staffid
where s.office in ('Glasgow', 'Bearsden')
What you are missing is the joins between the tables. You need to join to the intermediary table to get the relationship between the staff and car tables.
As far as car_allocation is an intermediate table, it's rather better to put it into the FROM clause and JOIN others:
SELECT car.rego
FROM car_allocation A
JOIN car ON A.car_id = car.car_id
JOIN stuff ON A.stuff_id = stuff.stuff_id
AND (staff.office = 'Glasgow' OR staff.office = 'Bearsden' -- OR some another condition, etc)
Pay attention to brackets, they groups conditions.
or
SELECT car.rego
FROM car_allocation A
JOIN car ON A.car_id = car.car_id
JOIN stuff ON A.stuff_id = stuff.stuff_ids
AND staff.office IN ('Glasgow', 'Bearsden')
If you have an enumeration you can use IN operator.
Also JOIN means the same as INNER JOIN. Here's MySQL manual considering JOIN syntax