MySQL日期范围查询问题:筛选无指定时段预订的产品
优化MySQL查询:筛选指定时段无预订的产品
原查询存在两个核心问题:
- RIGHT JOIN搭配WHERE条件会过滤掉从未有过任何预订记录的产品(因为
b.check_in_date为NULL时,WHERE条件不成立) - 日期冲突的判断逻辑错误,无法识别「入住早于指定范围但退房晚于指定范围」「入住早于指定范围且退房在指定范围内」「入住在指定范围内且退房晚于指定范围」这些重叠场景
正确的日期冲突逻辑
两个时间段[指定开始日期, 指定结束日期]和[预订入住日期, 预订退房日期]存在重叠的条件是:
b.check_in_date < @指定结束日期 AND b.check_out_date > @指定开始日期
只要产品存在满足该条件的预订,就说明它在指定时段有占用,反之则是我们需要的无预订产品。
优化方案
以下两种方案均能覆盖所有场景,且效率较高:
方案一:使用NOT EXISTS子查询
SELECT p.* FROM products p WHERE NOT EXISTS ( SELECT 1 FROM bookings b WHERE b.product_id = p.id AND b.check_in_date < '2022-11-25' -- 替换为你的指定时段结束日期参数 AND b.check_out_date > '2022-11-10' -- 替换为你的指定时段开始日期参数 );
该查询直接检查当前产品是否没有任何与指定时段重叠的预订,符合要求的产品(包括从未预订过的)会被返回。
方案二:使用LEFT JOIN + IS NULL
SELECT p.* FROM products p LEFT JOIN bookings b ON p.id = b.product_id AND b.check_in_date < '2022-11-25' AND b.check_out_date > '2022-11-10' WHERE b.id IS NULL;
通过LEFT JOIN保留所有产品,仅关联出与指定时段冲突的预订记录,最后过滤出未关联到任何冲突记录的产品(即b.id IS NULL),就是指定时段无预订的产品。
内容的提问来源于stack exchange,提问作者EFF
相关产品推荐
相关产品推荐

