如何使用SQL的DATEADD函数精准扣除法定节假日天数?

冬磊姑娘_6625

冬磊姑娘_6625

2026-09-24

318人浏览

原创

dateadd无法处理节假日,必须结合含调休标识的物理节假日表,用递归cte逐日倒推工作日;需显式设置datefirst,严格验证节前/节后/调休日边界。

如何使用sql的dateadd函数精准扣除法定节假日天数?

DATEADD 本身不处理节假日,必须配合节假日表使用

DATEADD 只做机械的日期加减,比如 DATEADD(day, -5, GETDATE()) 就是单纯往前推 5 个自然日,完全不识别元旦、春节或调休日。想“扣除法定节假日”,本质是「从起始日开始,逐日倒推,跳过所有节假日和周末,直到扣够指定工作日数」——这无法靠单条 DATEADD 实现,必须用循环、递归 CTE 或自连接查节假日表。

构造节假日表是前提,且必须包含调休上班日

很多失败案例源于节假日表太简陋:只列放假日期,没标“调休上班日”。比如 2024 年 2 月 17 日(周六)因春节调休要上班,如果表里没这条记录,系统会误判为周末跳过,导致多扣一天。

  • 表结构建议至少含:holiday_date(DATE)、is_workday(BIT,0=放假,1=调休上班)
  • 务必每年更新,国务院通知发布后及时入库,别依赖“自动计算”——清明/中秋等无固定公式
  • 避免用视图或函数动态生成节假日,DDL 不稳定、性能差;物理表 + 定期人工核对最可靠

用递归 CTE 倒推工作日比 WHILE 循环更可控

SQL Server 中,递归 CTE 能清晰表达“从目标日开始,每天检查是否为工作日,直到累计扣够 N 天”的逻辑,比手动写 WHILE 更易读、不易死循环。

WITH workdays AS (
  SELECT 
    DATEADD(day, -1, @target_date) AS dt,
    1 AS cnt
  UNION ALL
  SELECT 
    DATEADD(day, -1, dt),
    cnt + CASE 
      WHEN EXISTS (
        SELECT 1 FROM holidays h 
        WHERE h.holiday_date = DATEADD(day, -1, dt) 
          AND h.is_workday = 0
      ) OR DATEPART(weekday, DATEADD(day, -1, dt)) IN (1,7) -- 周日=1、周六=7(SET DATEFIRST 7)
      THEN 0 ELSE 1 END
  FROM workdays 
  WHERE cnt <p>注意:<code>DATEPART(weekday, ...)</code> 返回值受 <code>SET DATEFIRST</code> 影响,生产环境必须显式设置,不能依赖默认值。</p><h3>WHERE 条件里直接过滤节假日会导致结果偏移</h3><p>常见错误写法:<code>SELECT TOP (@n) date FROM calendar WHERE is_holiday = 0 ORDER BY date DESC</code>。这会取出最近的 N 个非假日,但不保证这些日期在逻辑上是连续倒推的——比如某天是假期,前后两天都是工作日,这条语句会跳过假期取更早的日期,造成实际跳过的天数 > N。</p>
  • 必须按时间顺序逐日判断,不能“批量筛选后取 Top”
  • 如果用窗口函数,ROW_NUMBER() OVER (ORDER BY date DESC) 也要先排除节假日再编号,否则序号不连续
  • 测试时重点验证节前最后一个工作日、节后第一个工作日、调休日这三类边界点

节假日逻辑不是纯数学运算,它依赖行政公告和人工校准。哪怕代码跑通,每年初也得拉出当年节假日表和日历对照一遍,漏掉一个调休日,整套排期就偏了。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

3743

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

791

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

969

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

5521

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

2503

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

5520

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

7181

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

970

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

852

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.1万人学习