SQL query that limits results based on appearance in other tables - sql

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.

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 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

List the names of the course(s) student Altvater took in semester I-2008

Im stuck on a question "List the names of the course(s) student Altvater took in semester I-2008" If anyone can guide me to the right direction I would appreciate it. I assume i would use some sort of join. Please refer to this diagram http://www.csc.villanova.edu/~mdamian/Past/databasefa13/notes/ch07-inclassex.pdf
I understand that I will below parts in my query
Where StudentName = 'Altvater' and
Where Semester = ‘I-2008’
Column names are consistent throughout the schema, allowing natural joins:
SELECT DISTINCT CourseName
FROM STUDENT
NATURAL JOIN REGISTRATION
NATURAL JOIN SECTION
NATURAL JOIN COURSE
WHERE StudentName = 'Altvater'
AND Semester = 'I-2008';
Try following SQL:
SELECT COURSENAME
FROM STUDENT S
INNER JOIN REGISTRATION R
ON S.STUDENTID=R.STUDENTID
INNER JOIN SECTION SE
ON R.SECTOINNO=SE.SECTOINNO
AND R.SEMESTER=SE.SEMESTER
INNER JOIN COURSE C
ON SE.COURSEID=C.COURSEID
WHERE S.STUDENTID=54907/* Altvater */
AND R.SEMESTER='I-2008'
You just need to understand basic design of tables to write SQL. SQL is very easy language. Let me know if you have any doubt in this query.

I am unable to return all values using joins in my sql query, what am I doing wrong?

I have three tables - Assignment, Grades, Student and I am trying to make this query work so that it returns all assignments even if there is no grade entered for a student yet.
The tables are setup like this
Assignment
AssignmentId, AssignmentName, PointsPossible
Grades (Junction table)
StudentId, AssignmentId, PointsReceived
Student
StudentId, StudentName
My query:
select
s.StudentName, a.AssignmentName, g.PointsReceived, a.PointsPossible
from
student s
cross join
assignment a
left outer join
grades g on s.StudentId = g.StudentId and g.AssignmentId = a.AssignmentId
order by
s.StudentName;
When I run the query I get all the names I need, but I don't get all the assignments back. I should be getting all the names, all the assignments, and if the assignment hasn't been graded yet, there should be a null value returned.
I need a little direction, maybe my tables are setup incorrectly.
You need to get all assignments even if there isn't a grade? The obvious question is: without a junction table, how do you know which assignments to provide for each student?
So, let me guess that you want to get a cross product of all students and all assignments, along with grades (if any). If so, you want to structure your query like this:
select s.StudentName, a.AssignmentName, a.PointsPossible, g.PointsReceived
from students s cross join
assignments a left outer join
grades g
on g.StudentId = a.StudentId and g.AssignmentId = a.AssignmentId;
order by s.StudentName;

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