【问题标题】:Combine multiple room availability queries into one将多个房间可用性查询合并为一个
【发布时间】:2011-02-11 14:31:18
【问题描述】:

我目前正在尝试通过组合查询来优化数据库。但在优化房间可用性查询时,我总是遇到死胡同。

我有一个房间可用性表,其中每条记录都说明了每个日期的可用房间数量。它的格式如下:

  • room_availability_id (PK)
  • room_availability_rid (fk_room_id)
  • room_availability_date (2011-02-11)
  • room_availability_number(可用房间数)

麻烦在于获取在提供的每一天都有可用的房间列表。当我像这样使用 IN() 时:

WHERE room_availability_date IN('2011-02-13','2011-02-14','2011-02-15')
AND room_availability_number > 0

如果 14 日的可用性为 0,它仍然会给我其他 2 个日期。但我只想要那个 room_id 在所有三个日期都可用的时候。

请告诉我,除了单独查询每个日期/房间/可用性组合之外,还有一种方法可以在 MySQL 中执行此操作(这就是现在所做的 :-()

我尝试了各种组合,尝试使用 room_availability_date = ALL (...),尝试了一些肮脏的重复子查询但无济于事。

提前感谢您的任何想法!

【问题讨论】:

    标签: mysql query-optimization


    【解决方案1】:

    您需要构造一个查询来对房间 ID 进行分组,然后检查每个日期是否有空房,这可以使用 having 子句来完成。将 where 子句谓词保留在 room_availability_date 中将有助于保持查询效率(因为索引等不能轻易地与 have 子句一起使用)。

    SELECT 
        room_availability_rid
    
    WHERE room_availability_date IN ('2011-02-13','2011-02-14','2011-02-15')
      AND room_availability_number > 0
    
    GROUP BY room_availability_rid 
    
    HAVING count(case room_availability_date when '2011-02-13' THEN 1 END) > 0
       AND count(case room_availability_date when '2011-02-14' THEN 1 END) > 0
       AND count(case room_availability_date when '2011-02-15' THEN 1 END) > 0
    

    【讨论】:

    • 通过简单地计算进入每个组的行来简化这一点。 (可以假设每个房间每天只有一条记录吗?)
    • 谢谢你!我做了一个快速测试,它确实看起来很完美!我将不得不做一些彻底的测试,看看它是否可以用于完整查询中的更多位置。 @awm:是的,每个房间/日期/可用性组合应该只有 1 条记录。越优化越好!
    【解决方案2】:

    我认为我可以改进 a'r 的答案:

    SELECT 
        room_availability_rid, count(*) n
    
    WHERE room_availability_date IN ('2011-02-13','2011-02-14','2011-02-15')
      AND room_availability_number > 0
    
    GROUP BY room_availability_rid 
    
    HAVING n=3
    

    编辑:这当然假设每个房间每天只有一个表条目。这是一个有效的假设吗?

    【讨论】:

    • 谢谢Awm,这似乎也很完美!因为是的,应该只有 1 个房间/日期/号码组合。
    【解决方案3】:

    您可以按房间 ID 分组,生成可用日期列表,然后查看是否包含您需要的所有日期。

    这将为您提供每个房间的可用日期列表:

    select `room_availability_rid`,group_concat(`room_ availability_date`) as `datelist`
           from `table` where room_availability_number>0 
           group by `room_availability_rid`
    

    然后我们可以添加一个having子句来获取在我们需要的所有日期都有可用的房间:

    select `room_availability_rid`,group_concat(`room_ availability_date`) as `datelist`
            from `table` where room_availability_number>0
            group by `room_availability_rid`
            having find_in_set('2011-02-13',`datelist`) and
                   find_in_set('2011-02-14',`datelist`) and
                   find_in_set('2011-02-15',`datelist`)
    

    这应该可以。给我测试一下好吗? :)

    【讨论】:

      猜你喜欢
      • 2021-06-20
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      • 2016-02-05
      • 2019-07-11
      • 2016-04-02
      • 1970-01-01
      相关资源
      最近更新 更多