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

SQL Server技术求助:如何生成未出现在指定表中的设施与日期组合列表?

解决SQL Server中生成缺失的设施-日期组合问题

嘿,你已经走到最后50米了,就差几个小细节调整!你的整体思路完全正确——先生成所有设施和日期的可能组合,再排除已经存在于table1中的组合,但你的NOT EXISTS子查询里有几个错误导致结果不对:

  • 变量引用错误:你在子查询里写了between StartDate and EndDate,但这里应该用你声明的变量@StartDate和@EndDate,漏了@符号会导致SQL无法识别变量
  • 无意义的空值判断:t2.FACILITY is null这个条件完全没必要,因为cte_FacilityReportingDates里的Facility是从table1取的去重值,不可能为空,加上这个条件会让子查询永远找不到匹配记录,最终NOT EXISTS会返回所有组合,这显然不是你要的结果
  • 多余的GROUP BY:NOT EXISTS只需要判断是否存在匹配的记录,子查询里的group by t1.facility, t1.REPORTING_DATE完全多余,反而会干扰判断

修正后的完整代码

declare @StartDate date = '08/01/2021', @EndDate Date = '08/04/2021';

with cte_FacilityReportingDates as (
 -- 提取table1中已存在的设施-日期组合
 select distinct Facility, REPORTING_DATE 
 from table1 
 where REPORTING_DATE between @StartDate and @EndDate
),
cte_facility as (
 -- 获取所有唯一设施
 select distinct Facility from table1
),
cte_ReportingDates as (
 -- 获取指定日期范围内的所有唯一日期
 select distinct REPORTING_DATE 
 from table1 
 where REPORTING_DATE between @StartDate and @EndDate
),
cte_Combine as (
 -- 生成所有可能的设施-日期笛卡尔积
 select f.Facility, d.REPORTING_DATE 
 from cte_facility f cross join cte_ReportingDates d
)
-- 从所有组合中排除已存在的记录
select t1.FACILITY, t1.REPORTING_DATE 
from cte_Combine t1
where not exists (
 select 1 
 from cte_FacilityReportingDates t2 
 where t1.FACILITY = t2.FACILITY 
 and t1.REPORTING_DATE = t2.REPORTING_DATE -- 直接匹配日期,无需重复判断范围
);

额外优化建议

如果你的table1中日期可能不连续(比如某些日期没有任何记录),而你需要生成完整的连续日期范围(而非仅取table1中存在的日期),可以把cte_ReportingDates改成生成连续日期的CTE,示例如下:

cte_ReportingDates as (
 -- 生成@StartDate到@EndDate的连续日期
 select @StartDate as REPORTING_DATE
 union all
 select dateadd(day, 1, REPORTING_DATE)
 from cte_ReportingDates
 where REPORTING_DATE < @EndDate
)

内容的提问来源于stack exchange,提问作者Keith Johnson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 03:22:49