【问题标题】:SQL IN Clause - get back IN elements that did not matchSQL IN 子句 - 取回不匹配的 IN 元素
【发布时间】:2017-05-28 09:40:44
【问题描述】:

我想运行一个 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”?

【问题讨论】:

  • 尝试使用IFNULL条件,能否告诉我们哪个表存储了乘员姓名?
  • 问题是,当您查询时,您的表中实际上是什么?
  • 这里的桌子设计很差。 Rooms 表应包括所有表 - 无论它们是否有居住者!

标签: mysql sql in-clause


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    您应该有两个单独的表。一个带有房间列表,第二个在现有表上,然后您可以通过 LEFT join experession 进行选择。

    例如,RoomList 表将如下所示:

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

    【讨论】:

      【解决方案3】:

      假设没有居住者的房间设置为 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
      

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-02-12
          • 2014-09-17
          • 2015-01-25
          • 2020-06-15
          • 2012-07-23
          • 1970-01-01
          • 1970-01-01
          • 2011-01-12
          相关资源
          最近更新 更多