I need to get all the students' details who either are in room number 6 or 7 or not at all in any room. If they are in other rooms, simply, I don't wish to have that record.
My schema is:
students(roll_no, name,class,...)
rooms(room_no,...)
student_room(room_no,roll_no).
students and rooms are related via student_room
table. But, I am unable to figure out how to write the query for this.
This will give you details of the students that are in rooms other than 6 or 7:
SELECT
s.*
FROM
student AS s
INNER JOIN student_room AS sr ON s.roll_no = sr.roll_no
WHERE
sr.room_no NOT IN (6, 7)
;
Now you just need to invert this logic to return the other subset. This is called an anti-join. There is no direct syntax for it in SQL but there are several ways of implementing it using existing syntax. If we take the above query as a starting point, the closest matching anti-join form would be the LEFT JOIN
+ WHERE IS NULL
method:
SELECT
s.*
FROM
student AS s
LEFT JOIN student_room AS sr ON s.roll_no = sr.roll_no
AND sr.room_no NOT IN (6, 7)
WHERE
sr.roll_no IS NULL
;
This is how it works:
The result of the join itself will contain all students from the student
table, as that table is on the left side of a left outer join.
The right side of the join will have data only if the corresponding student is not in room 6 or 7. Otherwise it will contain nulls.
The matching rows are excluded in the WHERE clause by checking that there is no match on the right side ( sr.roll_no IS NULL
; it would work the same with sr.roll_no IS NULL
provided sr.roll_no
cannot have nulls).
I figured it out.
SELECT * FROM students
INNER JOIN
(SELECT roll_no,CASE WHEN room_no=6 or room_no=7 THEN 1
WHEN room_no IS NULL THEN 1
ELSE 0 END AS is_room
from student_room GROUP BY roll_no) AS room_info
ON students.roll_no=room_info.roll_no
AND room_info.is_room=1
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.