2017-01-13 50 views
1

我想运行SQL查询来确定多个房间的占有者。我也想看看哪些房间是空的。SQL IN子句 - 取回IN元素不匹配

我可以用表格的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子句没有返回结果,并显示“没有人”的要素是什么?

+0

尝试使用IFNULL条件,你能让我们知道哪些表存储占有者名称吗? –

+0

问题在于,当你查询时,你的表格中究竟有什么? –

+0

这里你有一个糟糕的桌子设计。房间表应该包括所有的桌子 - 不管他们是否有住客! – jarlh

回答

2

看起来您的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

0

假设没有乘客的房间都设置为NULL,你可以使用一个case语句:

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 
1

你应该有两个单独的表。一个房间列表,第二个在现有的桌子上,然后你可以选择LEFT加入预期。

例如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") 
0

只是一个单一的COALESCEISNULL将帮助你获得所需的输出。你几乎接近您的解决方案,并有很多方法,你可以在给定的答案看到,但我建议你到下面做轻微的改变,你的代码:

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

MYSQL,你可以以同样的方式使用IFNULL