将多个房间可用性查询合并为一个

Posted

技术标签:

【中文标题】将多个房间可用性查询合并为一个【英文标题】: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 (...),尝试了一些肮脏的重复子查询但无济于事。

提前感谢您的任何想法!

【问题讨论】:

【参考方案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`)

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

【讨论】:

以上是关于将多个房间可用性查询合并为一个的主要内容,如果未能解决你的问题,请参考以下文章

选择日期之间的房间可用性(sql查询)

如何在 Django 中检查或设置房间可用性

检查日期范围内所选房间的可用性

设计一个高性能的酒店房间预订系统

MySql 查询以查找给定日期“从”和“到”可用的房间

合并多个相同的 Kafka Streams 主题