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

如何使用SQL计算两个日期之间不含节假日的工作日?

计算两个日期间的工作日(不含节假日)SQL实现

核心思路是:先计算日期范围内的总周一至周五天数,再减去该范围内属于工作日的节假日数量。通过维护统一的节假日表替代手动计算,后续仅需更新表数据即可。

第一步:创建统一的节假日表

先建立一张用于管理所有节假日的表,结构简单易维护:

-- MySQL/PostgreSQL/SQL Server通用表结构
CREATE TABLE holidays (
    holiday_date DATE PRIMARY KEY,
    description VARCHAR(100) -- 可选,标注节假日名称
);

你可以手动插入节假日数据,或通过脚本批量导入每年的法定假日,比如:

INSERT INTO holidays (holiday_date, description)
VALUES 
('2024-01-01', '元旦'),
('2024-02-10', '春节'),
('2024-04-04', '清明节');

第二步:分数据库实现计算逻辑

以下是主流SQL数据库的具体查询代码,替换对应日期变量为你的目标日期即可。

MySQL

SET @start_date = '2024-01-01';
SET @end_date = '2024-01-31';

SELECT
  -- 计算总周一至周五天数
  (DATEDIFF(@end_date, @start_date) + 1
   - FLOOR((DATEDIFF(@end_date, @start_date) + WEEKDAY(@start_date)) / 7) * 2
   - CASE WHEN WEEKDAY(@start_date) = 5 THEN 1 ELSE 0 END -- 排除起始日为周六的情况
   - CASE WHEN WEEKDAY(@end_date) = 6 THEN 1 ELSE 0 END) -- 排除结束日为周日的情况
  -- 减去属于工作日的节假日数量
  - (SELECT COUNT(*) 
     FROM holidays 
     WHERE holiday_date BETWEEN @start_date AND @end_date
       AND WEEKDAY(holiday_date) NOT IN (5, 6)) AS working_days;

注:MySQL中WEEKDAY()返回0=周一,5=周六,6=周日。

PostgreSQL

WITH date_range AS (
  SELECT generate_series('2024-01-01'::DATE, '2024-01-31'::DATE, '1 day') AS date
)
SELECT
  -- 统计日期范围内的周一至周五数量
  COUNT(*) 
  -- 减去属于工作日的节假日数量
  - (SELECT COUNT(*) 
     FROM holidays 
     WHERE holiday_date BETWEEN '2024-01-01' AND '2024-01-31'
       AND EXTRACT(DOW FROM holiday_date) NOT IN (0, 6)) AS working_days
FROM date_range
WHERE EXTRACT(DOW FROM date) NOT IN (0, 6); -- 0=周日,6=周六

SQL Server

DECLARE @start_date DATE = '2024-01-01';
DECLARE @end_date DATE = '2024-01-31';

SELECT
  -- 计算总周一至周五天数
  (DATEDIFF(day, @start_date, @end_date) + 1)
  - (DATEDIFF(week, @start_date, @end_date) * 2)
  - CASE WHEN DATEPART(weekday, @start_date) = 1 THEN 1 ELSE 0 END -- 排除起始日为周日
  - CASE WHEN DATEPART(weekday, @end_date) = 7 THEN 1 ELSE 0 END -- 排除结束日为周六
  -- 减去属于工作日的节假日数量
  - (SELECT COUNT(*) 
     FROM holidays 
     WHERE holiday_date BETWEEN @start_date AND @end_date
       AND DATEPART(weekday, holiday_date) NOT IN (1, 7)) AS working_days;

注:SQL Server默认DATEPART(weekday)返回1=周日,7=周六,若你的数据库设置不同需调整对应数值。

注意事项

  • 上述计算包含起始日和结束日,若不需要包含某一端,调整日期范围或DATEDIFF参数即可。
  • 节假日表需定期更新,比如每年年初导入当年的法定节假日,确保计算准确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 08:01:02