You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL酒店数据库查询指定时间段未预订房间的SQL语句错误排查求助

MySQL酒店数据库查询指定时间段未预订房间的SQL语句错误排查求助

兄弟,我懂你现在的头疼之处——你想找出2022-05-01到2022-05-10这段时间内没有被预订的房间,但目前的查询结果只返回那些从来没有过任何预订记录的“空房间”,完全不符合预期对吧?

咱们来拆解下问题出在哪:你写的JOIN条件里的时间判断逻辑太窄了!

你原来的条件是:

AND reservation.checkin <= '2022-05-01'
AND reservation.checkout > '2022-05-10'

这个条件只会匹配完全覆盖目标时间段的预订(比如客人4月28入住,5月12退房),然后你通过WHERE reservation.id IS NULL排除掉这些房间。但问题是,那些在目标时间段内有部分占用的房间(比如5月3日入住、5月8日退房),根本不会被这个JOIN条件匹配到,导致本该被排除的房间反而被保留了,最终结果就只剩完全没预订过的房间。

要找出指定时间段未被预订的房间,本质是要排除所有存在与目标时间段重叠的预订的房间。而两个时间段重叠的情况包括:

  • 预订的入住日期落在目标时间段内(比如checkin是2022-05-03)
  • 预订的退房日期落在目标时间段内(比如checkout是2022-05-08)
  • 预订的时间段完全包裹住目标时间段(就是你原来条件里的情况)

所以正确的时间判断逻辑应该是:预订的入住日期早于目标时间段的结束,且预订的退房日期晚于目标时间段的开始,这个条件能覆盖所有重叠的情况。

给你两个修正后的写法,选你顺手的用:

写法一:LEFT JOIN 版本

SELECT room.*
FROM room
LEFT JOIN reservation
ON room.idRoom = reservation.idRoom
AND reservation.checkinDate < '2022-05-10'  -- 预订入住早于目标时间段结束
AND reservation.checkoutDate > '2022-05-01' -- 预订退房晚于目标时间段开始
WHERE reservation.idReservation IS NULL

写法二:NOT EXISTS 版本(逻辑更直观)

SELECT room.*
FROM room
WHERE NOT EXISTS (
    SELECT 1
    FROM reservation
    WHERE reservation.idRoom = room.idRoom
    AND reservation.checkinDate < '2022-05-10'
    AND reservation.checkoutDate > '2022-05-01'
)

这两种写法的逻辑都是:找出所有房间,排除掉那些存在任何与目标时间段重叠的预订的房间,剩下的就是你要的这段时间完全空闲的房间——不管这些房间之前有没有过其他时间段的预订。

试试调整后应该就能得到正确结果啦!

备注:内容来源于stack exchange,提问作者Marawan Emad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 14:42:38