SQL:DATE_ADD(日期,INTERVAL expr类型)跳过周末

时间:2016-02-27 02:02:03

标签: mysql sql

我目前正在使用DATE_ADD(date,INTERVAL expr type)将截止日期设置为mySQL数据库中的触发器。

我想知道的是,作为触发器的一部分,是否可以跳过周末(周六,周日)。

2 个答案:

答案 0 :(得分:1)

你必须创建一个自己的功能来做到这一点。您可以在this answer中查看如何执行此操作(例如,使用function代替procedure)。至于如何编写这样的函数,here是一个工作算法。代码非常简单:它会循环播放数天并跳过周末。

CREATE FUNCTION `DAYSADDNOWK`(addDate DATE, numDays INT) RETURNS date
BEGIN
    IF (WEEKDAY(addDate)=5) THEN
        SET addDate=DATE_ADD(addDate, INTERVAL 1 DAY);
    END IF;
    IF (WEEKDAY(addDate)=6) THEN
        SET addDate=DATE_ADD(addDate, INTERVAL 1 DAY);
    END IF;
    WHILE numDays>0 DO
       SET addDate=DATE_ADD(addDate, INTERVAL 1 DAY);
       IF (WEEKDAY(addDate)=5) THEN
           SET addDate=DATE_ADD(addDate, INTERVAL 1 DAY);
       END IF;
       IF (WEEKDAY(addDate)=6) THEN
           SET addDate=DATE_ADD(addDate, INTERVAL 1 DAY);
       END IF;
       SET numDays=numDays-1;
    END WHILE;
    RETURN addDate;
END

目前SELECT DAYSADDNOWK(CURDATE(), 5)会产生2016-03-07,这是正确的。

当然你只能在几天内使用它,所以没有任意interval,但你的问题提到了date数据类型,而且我不太清楚如何添加一个月不计算工作日。

答案 1 :(得分:0)

这个函数只是创建一个从参数中给出的日期开始的日期列表,然后在忽略第1天和第7天(分别是星期日和星期六)时确定哪个日期是x天数(间隔)。 SQL Server)。

CREATE FUNCTION [dbo].[udf_days_add_no_wknd] 
    (
    @start_date date
    , @interval int
    )
RETURNS date
AS
BEGIN

declare @answer date

; with dates as 
    (
        select @start_date as date_val
        union all
        select dateadd(d, 1, date_val) as date_val
        from dates
        where date_val < dateadd(d, @interval * 10, @start_date)
    )
    , final as
    (
        select top 1 lead(ld.date_val, @interval, NULL) over (order by ld.date_val asc) as new_date_val
        from dates as ld
        where 1=1
        and datepart(dw, ld.date_val) not in (1,7) --eliminating weekends
    )
select @answer = (select new_date_val from final)

return @answer

END

考虑到使用lead()函数,此解决方案依赖于SQL Server 2012或更高版本,这一点毫无价值。