如何在SQL中计算指定日期至当前日期的工作日天数?
计算指定日期到当前日期的工作日数量(基于dimDate表)
核心逻辑是统计[ARCUSYM000].[dbo].[dimDate]表中,从目标日期(FullDate)到当前日期区间内,BusinessDay标记为工作日的记录总数。以下是几种可行的实现方法:
方法1:关联子查询(兼容所有SQL Server版本)
适合中小规模数据查询,逻辑直观易懂:
SELECT d.FullDate, -- 统计区间内的工作日数量 (SELECT COUNT(*) FROM [ARCUSYM000].[dbo].[dimDate] dd WHERE dd.FullDate BETWEEN d.FullDate AND CAST(GETDATE() AS DATE) AND dd.BusinessDay = 1) AS WorkDayCount FROM [ARCUSYM000].[dbo].[dimDate] d -- 可选:仅处理不晚于当前日期的记录,若需包含未来日期可删除此条件 WHERE d.FullDate <= CAST(GETDATE() AS DATE);
说明:
- 使用
CAST(GETDATE() AS DATE)去除时间部分,避免与FullDate的日期类型不匹配导致的区间错误。 - 若
FullDate晚于当前日期,子查询会返回0,可根据需求调整为返回NULL或负数。
方法2:窗口函数累加(SQL Server 2012+,高效批量处理)
当需要处理大量数据时,窗口函数的效率远高于子查询:
WITH DateCumulative AS ( SELECT FullDate, BusinessDay, -- 计算从最早日期到当前日期的累计工作日数 SUM(BusinessDay) OVER (ORDER BY FullDate) AS CumulativeWorkDays FROM [ARCUSYM000].[dbo].[dimDate] ) SELECT d.FullDate, -- 当前日期累计工作日数 - 目标日期前一天的累计工作日数 ISNULL(current_day.CumulativeWorkDays, 0) - ISNULL(prev_day.CumulativeWorkDays, 0) AS WorkDayCount FROM DateCumulative d LEFT JOIN DateCumulative current_day ON current_day.FullDate = CAST(GETDATE() AS DATE) LEFT JOIN DateCumulative prev_day ON prev_day.FullDate = DATEADD(day, -1, d.FullDate) WHERE d.FullDate <= CAST(GETDATE() AS DATE);
说明:
- 先通过CTE生成每个日期的累计工作日总数,再通过差值计算区间内的工作日数量,避免重复扫描表。
方法3:支持未来日期的正负计数
如果需要对晚于当前日期的FullDate返回负数工作日数(表示从当前日期到该未来日期的工作日数取反),可使用此方法:
SELECT d.FullDate, SIGN(DATEDIFF(day, d.FullDate, GETDATE())) * (SELECT COUNT(*) FROM [ARCUSYM000].[dbo].[dimDate] dd WHERE dd.FullDate BETWEEN CASE WHEN d.FullDate <= GETDATE() THEN d.FullDate ELSE GETDATE() END AND CASE WHEN d.FullDate <= GETDATE() THEN GETDATE() ELSE d.FullDate END AND dd.BusinessDay = 1) AS WorkDayCount FROM [ARCUSYM000].[dbo].[dimDate] d;
说明:
SIGN()函数判断日期先后:FullDate早于当前日期返回1,晚于返回-1,相等返回0,以此实现正负计数。
注意事项
- 确保
dimDate表包含完整的日期序列,无缺失日期,否则会导致计数不准确。 - 确认
BusinessDay字段的取值逻辑(通常1=工作日,0=休息日/节假日),避免统计错误。
内容的提问来源于stack exchange,提问作者Timothy Meyer
相关产品推荐
相关产品推荐

