Snowflake技术咨询:Dateadd函数能否仅添加工作日?
如何在日期函数中仅添加工作日?
当然可以实现!普通的dateadd(day, 10, business_date)会把周末和节假日也算进去,但我们可以根据你使用的数据库,用内置函数或者自定义逻辑来精准计算未来10个工作日。下面分几种常见数据库给你具体方案:
1. SQL Server(2022及以上版本)
SQL Server 2022引入了专门的DATEADD_WORKDAY函数,直接就能满足需求,不需要自己写复杂逻辑:
SELECT DATEADD_WORKDAY(10, business_date) AS next_10_workdays;
如果你的版本低于2022,就需要自定义函数来跳过周末(如果要排除节假日,还得配合节假日表)。比如这个简单的自定义函数:
CREATE FUNCTION dbo.AddWorkdays(@StartDate DATE, @Workdays INT) RETURNS DATE AS BEGIN DECLARE @CurrentDate DATE = @StartDate; DECLARE @DaysAdded INT = 0; WHILE @DaysAdded < @Workdays BEGIN SET @CurrentDate = DATEADD(DAY, 1, @CurrentDate); -- 跳过周六(6)和周日(0) IF DATEPART(WEEKDAY, @CurrentDate) NOT IN (1, 7) BEGIN SET @DaysAdded = @DaysAdded + 1; END END RETURN @CurrentDate; END;
调用的时候用:
SELECT dbo.AddWorkdays(business_date, 10) AS next_10_workdays;
2. MySQL
MySQL没有内置的工作日添加函数,但可以写一个自定义存储函数来实现:
DELIMITER // CREATE FUNCTION AddWorkdays(start_date DATE, num_days INT) RETURNS DATE DETERMINISTIC BEGIN DECLARE current_date DATE; DECLARE days_added INT; SET current_date = start_date; SET days_added = 0; WHILE days_added < num_days DO SET current_date = ADDDATE(current_date, 1); -- 跳过周六(6)和周日(0) IF WEEKDAY(current_date) NOT IN (5, 6) THEN SET days_added = days_added + 1; END IF; END WHILE; RETURN current_date; END // DELIMITER ;
使用时直接调用:
SELECT AddWorkdays(business_date, 10) AS next_10_workdays;
3. PostgreSQL
PostgreSQL可以借助generate_series生成日期序列,然后过滤掉周末,再取第10个工作日:
SELECT ( SELECT d::DATE FROM generate_series(business_date + INTERVAL '1 day', business_date + INTERVAL '20 day', INTERVAL '1 day') d WHERE EXTRACT(DOW FROM d) NOT IN (0, 6) -- 0=周日,6=周六 LIMIT 1 OFFSET 9 -- 偏移9取第10个(索引从0开始) ) AS next_10_workdays;
如果需要排除节假日,只要在WHERE条件里加上AND d::DATE NOT IN (SELECT holiday_date FROM your_holidays_table)即可。
通用注意事项
- 如果你需要排除法定节假日,上面的基础逻辑都需要配合一个存储节假日日期的表,在过滤的时候排除这些日期。
- 不同数据库对一周起始日的定义可能不同(比如SQL Server默认周日是一周第一天,PostgreSQL默认周一),写逻辑的时候要注意调整判断条件。
内容的提问来源于stack exchange,提问作者sridark
相关产品推荐
相关产品推荐

