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

SQL一对多关联下查询指定日期未预约产品的左连接问题

问题根因

  • 左关联后无预约的产品对应的reservation表所有字段均为NULL,你将预约时间的过滤放在WHERE子句中,NULL和任意值做比较都会返回UNKNOWN,会被WHERE条件直接过滤,因此无预约的产品不会出现在结果中。
  • 原有时间范围判断逻辑有误,没有正确识别预约和目标时间段的重叠关系,也会导致结果不符合预期。

解决方案

方案1:将时间过滤移到LEFT JOIN的ON子句中

把预约的时间过滤条件从WHERE移到LEFT JOIN reservation的ON条件里,仅关联和目标时间段重叠的预约,再过滤没有匹配到预约的产品即可,修改后SQL如下:

SELECT
    p.idProduct, p.name, p.description, p.latitude, p.longitude, p.address,
    p.qualification, p.favourite,p.idCategory,p.idCity, p.rules, p.health, p.politics
FROM
    product p 
LEFT JOIN 
    city c ON c.idCity = p.idCity 
LEFT JOIN 
    reservation r ON r.idProduct = p.idProduct 
    -- 仅关联和目标时间段[2021-11-20, 2021-11-28]重叠的预约
    AND r.startDate <= '2021-11-28' 
    AND r.endDate >= '2021-11-20'
WHERE
    p.idCity = 1 
    -- 没有匹配到重叠预约的产品即为符合要求的产品
    AND r.idReservation IS NULL;

方案2:使用NOT EXISTS实现(逻辑更直观)

直接用NOT EXISTS判断产品不存在和目标时间段重叠的预约即可,天然包含无任何预约的产品,SQL如下:

SELECT
    p.idProduct, p.name, p.description, p.latitude, p.longitude, p.address,
    p.qualification, p.favourite,p.idCategory,p.idCity, p.rules, p.health, p.politics
FROM product p
WHERE p.idCity = 1
AND NOT EXISTS (
    SELECT 1 FROM reservation r
    WHERE r.idProduct = p.idProduct
    AND r.startDate <= '2021-11-28' 
    AND r.endDate >= '2021-11-20'
)

注:判断两个时间段重叠的通用逻辑为「A的开始时间小于等于B的结束时间,且A的结束时间大于等于B的开始时间」,可以覆盖所有重叠场景。

内容的提问来源于stack exchange,提问作者Laura Nieto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 02:54:01