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

SQL Server:基于日期范围关联查询计算工作日需求

解决方案:计算扣除公共假期后的实际工作日

我来帮你搞定这个计算实际工作日的需求,核心思路就是针对Query1里的每一条记录,统计QueryHol中落在Due_Date到Received_Date区间内的公共假期总数,再用原有的天数差Diff减去这个假期数,就能得到实际的工作日天数了。

下面给你两种常用的实现方式,你可以根据自己的数据库类型和数据规模来选择:

方法一:关联子查询(写法直观,适合小数据量)

这种方式逻辑清晰,每条Query1记录单独查询对应的假期数,新手也容易理解:

SELECT
    q1.Due_Date,
    q1.Received_Date,
    q1.Diff,
    -- 统计当前记录区间内的假期总数
    (SELECT SUM(qh.Count) 
     FROM QueryHol qh 
     WHERE qh.Date BETWEEN q1.Due_Date AND q1.Received_Date) AS Holiday_Count,
    -- 用原天数差减去假期数,COALESCE处理无假期的情况(避免NULL)
    q1.Diff - COALESCE((SELECT SUM(qh.Count) 
                        FROM QueryHol qh 
                        WHERE qh.Date BETWEEN q1.Due_Date AND q1.Received_Date), 0) AS Actual_Working_Days
FROM Query1 q1;

关键细节:

  • BETWEEN会包含Due_Date和Received_Date当天的假期,如果你的业务逻辑需要排除某一端,可以改成qh.Date >= q1.Due_Date AND qh.Date < q1.Received_Date这类条件
  • COALESCE的作用是当区间内没有假期时,把NULL转换成0,这样Actual_Working_Days就等于原来的Diff,不会出现计算错误

方法二:LEFT JOIN + GROUP BY(性能更优,适合大数据量)

如果你的Query1和QueryHol数据量比较大,这种方式效率更高,因为只需要扫描两张表一次:

SELECT
    q1.Due_Date,
    q1.Received_Date,
    q1.Diff,
    -- 聚合统计假期数,COALESCE处理无假期的情况
    COALESCE(SUM(qh.Count), 0) AS Holiday_Count,
    -- 计算实际工作日
    q1.Diff - COALESCE(SUM(qh.Count), 0) AS Actual_Working_Days
FROM Query1 q1
-- 左连接确保即使没有匹配的假期,Query1的记录也会保留
LEFT JOIN QueryHol qh
    ON qh.Date BETWEEN q1.Due_Date AND q1.Received_Date
-- 按Query1的唯一字段分组,保证每条记录对应一个统计结果
GROUP BY q1.Due_Date, q1.Received_Date, q1.Diff;

额外提示:

  • 确保两张表的日期字段类型一致,比如都是DATE类型,避免因为类型不匹配导致关联失败
  • 如果QueryHol里存在重复的假期日期(虽然Count都是1,但重复的话SUM会多算),建议先去重,比如可以把QueryHol换成(SELECT DISTINCT Date, Count FROM QueryHol)来避免重复统计
  • 如果你的Diff是通过DATEDIFF计算出来的,要注意Diff的计算逻辑和假期统计的区间逻辑保持一致,比如如果Diff是DATEDIFF(day, Due_Date, Received_Date)(得到的是两个日期之间的天数差,不包含Due_Date当天),那假期统计的区间也要对应调整,避免多扣或少扣假期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:47:24