将多个房间可用性查询合并为一个
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`)
这应该可以。给我测试一下好吗? :)
【讨论】:
以上是关于将多个房间可用性查询合并为一个的主要内容,如果未能解决你的问题,请参考以下文章