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
相关产品推荐
相关产品推荐

