SQL IN Clause - get back IN elements that did not match

会有一股神秘感。 提交于 2019-12-08 07:00:52

问题


I'd like to run an SQL query to determine the occupants of a number of rooms. I'd also like to see which rooms are empty.

I can find the occupants using SQL of the form:

SELECT Room, OccupantName
FROM Rooms
WHERE Rooms IN ("Room 1", "Room 2", "Room 3", "Room 4")

However, if only Rooms 1 and 2 have occupants, eg

Room    OccupantName
Room 1, Person A
Room 2, Person B

how can I get something of the form:

Room    OccupantName
Room 1, Person A
Room 2, Person B
Room 3, Nobody
Room 4, Nobody

Is there a way to select out the elements of the IN clause that did not return results and show "Nobody"?


回答1:


It appears that your Rooms table only contains data for active occupancies. This makes sense in many ways, because you don't want to store information about people which aren't really occupying a room. But it poses a challenge to generate your desired result set, because the missing rooms aren't present in Rooms.

One option here is the "calendar table" approach. You can LEFT JOIN a table containing all rooms to your current Rooms table, and then label missing occupants as nobody.

SELECT t1.Room,
       COALESCE(t2.OccupantName, 'Nobody') AS OccupantName
FROM
(
    SELECT "Room 1" AS Room
    UNION ALL
    SELECT "Room 2"
    UNION ALL
    SELECT "Room 3"
    UNION ALL
    SELECT "Room 4"
) AS t1
LEFT JOIN Rooms AS t2
    ON t1.Room = t2.Rooms

Note that I used an line subquery to create a table for all rooms. In practice, you could create an actual table in Workbench containing this information.

Demo here:

SQLFiddle




回答2:


You should have two separate tables. one with list of rooms and second on the existing tables then you can select by LEFT join experession.

for example the RoomsList table will be like:

Room

Room 1

Room 2

Room 3

Room 4

Room 5

Room 6

Room 7

and then the query will be like:

SELECT Room, OccupantName

FROM RoomsList Left Join Rooms

ON RoomsList.Room=Rooms.Room

WHERE RoomsList.Room IN ("Room 1", "Room 2", "Room 3", "Room 4")



回答3:


Assuming the rooms without an occupant are set to NULL, you could use a case statement:

SELECT Room, CASE WHEN OccupantName IS NULL THEN 'Nobody' Else OccupantName END
FROM   Rooms
WHERE  Room IN ("Room 1", "Room 2", "Room 3", "Room 4")

Or just filter them out with a where clause:

SELECT Room, OccupantName
FROM   Rooms
WHERE  Room IN ("Room 1", "Room 2", "Room 3", "Room 4")
    AND OccupantName IS NOT NULL



回答4:


Just a single COALESCE or ISNULL will help you to get the desired output. You are almost near to your solution and there are many ways as you can see in the given answers but I suggest you to do slight change your code as below:

SELECT Room, COALESCE(OccupantName, 'Nobody') AS OccupantName
FROM Rooms
WHERE Rooms IN ('Room 1', 'Room 2', 'Room 3', 'Room 4')

For MYSQL you can use IFNULL in the same manner



来源:https://stackoverflow.com/questions/41627458/sql-in-clause-get-back-in-elements-that-did-not-match

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!