SQL IN子句 - 返回不匹配的IN元素

时间:2017-01-13 04:37:44

标签: mysql sql in-clause

我想运行一个SQL查询来确定多个房间的占用者。我还想看看哪些房间是空的。

我可以使用以下形式的SQL找到占用者:

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

但是,如果只有1号和2号房间有居住者,例如

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

我怎样才能获得某种形式:

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

有没有办法选择IN子句中没有返回结果并显示“Nobody”的元素?

4 个答案:

答案 0 :(得分:3)

您的Rooms表似乎只包含有效占用的数据。这在许多方面都很有意义,因为您不希望存储有关不占用房间的人的信息。但是,生成所需的结果集会带来挑战,因为Rooms中缺少空间。

这里的一个选项是“日历表”方法。您可以LEFT JOIN一个包含当前Rooms表格中所有会议室的表格,然后将遗失的占用者标记为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

请注意,我使用了行子查询为所有房间创建了一个表。实际上,您可以在Workbench中创建包含此信息的实际表。

在这里演示:

SQLFiddle

答案 1 :(得分:1)

您应该有两个单独的表。一个有房间列表,第二个有现有表格,那么你可以选择LEFT join experession。

例如RoomsList表将如下:

Room

Room 1

Room 2

Room 3

Room 4

Room 5

Room 6

Room 7

然后查询将如下:

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

答案 2 :(得分:0)

假设没有占用者的房间设置为NULL,您可以使用案例陈述:

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

或者只是用where子句过滤掉它们:

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

答案 3 :(得分:0)

只需一个COALESCEISNULL即可帮助您获得所需的输出。您几乎接近您的解决方案,您可以在给定的答案中看到很多方法,但我建议您稍微更改您的代码,如下所示:

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

对于MYSQL,您可以以相同的方式使用IFNULL