MYSQL添加工作日期

时间:2016-07-22 08:52:29

标签: mysql sql dateinterval

我想在提供的日期添加5天,但计算必须跳过周末。

我已经知道如何在不跳过周末的情况下添加5天:

SELECT DATE_ADD(`date_field`, INTERVAL 5 DAY) As FinalDate
FROM `table_name`;

现在我希望返回的值跳过周末。

目前,如果date_field = 2016-07-22结果为2016-07-27 但我希望结果为2016-07-29

7 个答案:

答案 0 :(得分:3)

试试这个:

SELECT DATE_ADD(
    date_field,
    INTERVAL 5 + 
    IF(
        (WEEK(date_field) <> WEEK(DATE_ADD(date_field, INTERVAL 5 DAY)))
        OR (WEEKDAY(DATE_ADD(date_field, INTERVAL 5 DAY)) IN (5, 6)),
        2,
        0)
    DAY
    ) AS FinalDate
FROM `table_name`;

工作原理:

  • 首先,它会在你的约会日期增加5天。
  • 其次,当date_field和5天后的两个星期相同时,必须再添加2天。
  • 第三,5天后SatSun,必须再添加2天。

答案 1 :(得分:0)

试试这个,应该很好地工作,基本上循环每一天并检查它们是星期六还是星期天,忽略它们。

https://social.technet.microsoft.com/wiki/contents/articles/30877.t-sql-extending-dateadd-function-to-skip-weekend-days.aspx

答案 2 :(得分:0)

我确实尝试过您的解决方案,但在使用间隔较大(例如20天)时遇到了问题。尽管如此,它的工作时间很短。

示例:for&#39; 2017-10-04&#39; + 20天,您的算法返回&#39; 2017-10-26&#39;。它应该是2017-11-01&#39;因为我们跳过了4个周末。

您添加的天数不是根据2周#之间的差异计算的,因此您可以添加的最大天数为2,在我的情况下,它应该是8(4x2)。

我修改了你的代码以结束这个(我还添加变量,更方便修改)

SELECT 
@ID:='2017-10-04' as initial_date, -- the initial date in the right format to manipulate (add x day)
@DTA:=20 as days_to_add, -- number of days to add
@DA:= DATE_ADD(@ID, INTERVAL @DTA DAY) as date_add,
@LASTDAY := WEEKDAY(@DA) as last_day, -- the day (Monday, Tuesday...) corresponding to the initial date + number of days to add
@WEEK1 := DATE_FORMAT(@ID, '%v') as initial_date_week, -- format the initial date to match week mode 3 (Monday 1-53)
@WEEK2 := DATE_FORMAT(@DA, '%v') as added_date_week_nbr, -- the week # of the initial_date + number of days to add
@WEEKDIFF := @WEEK2 - @WEEK1 as week_difference, -- the difference between week 2 and week 1
DATE_ADD(@ID,
        INTERVAL @DTA + 
            if ( @WEEKDIFF > 0 or @LASTDAY in (5,6),
              2,
              0
              ) + 
             if (@WEEKDIFF > 1,
             @WEEKDIFF*2,
             0
             ) DAY
    ) AS FinalDate

我得到我的周数的方式看起来很奇怪,但这是因为我在法国运行这个,而我的数据库似乎配置的方式是周数本周从星期日开始,&#34;%v& #34;代表&#39;模式3&#39;几周以来,您可以在此处查看MySQL文档以获取更多详细信息:https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html(ctrl + F&gt;&#39;%v&#39;)

我还没有实施公共假期,但我想在计算中添加X天,每天有一天是我们正在查看的时期。

根据我的(少数)测试,这应该工作。如果不是,请告诉我

答案 3 :(得分:0)

加上节假日1或2

select GREATEST(WEEKDAY(NOW()) - 4, 0) 'hollydays'

答案 4 :(得分:0)

我的解决方案是创建一个返回计算日期的函数,它将考虑连续的周末:

DELIMITER $$
CREATE FUNCTION `add_working_days_to_current_month`(ndays INT) RETURNS DATE
NO SQL 
BEGIN

    declare finalDate, startDate, originalFinalDate DATE;
    declare weekNumberStartDate, weekNumberEndDate, weekDiff INT;
    
    set startDate = DATE(CONCAT(YEAR(DATE_SUB(current_date(), INTERVAL 1 MONTH)),"-",MONTH(DATE_SUB(current_date(), INTERVAL 1 MONTH)),"-",DAY(LAST_DAY(DATE_SUB(current_date(), INTERVAL 1 MONTH)))));
    set weekNumberStartDate = WEEK(startDate);
    set finalDate = DATE_ADD(startDate, INTERVAL ndays DAY);
    set originalFinalDate = finalDate;
    set weekNumberEndDate = WEEK(finalDate);
    
    IF(weekNumberEndDate != weekNumberStartDate) THEN
        set weekDiff = (weekNumberEndDate - weekNumberStartDate) * 2;
        set finalDate = DATE_ADD(finalDate, INTERVAL weekDiff DAY);
    END IF;
    
    set weekNumberStartDate = WEEK(originalFinalDate);
    set weekNumberEndDate = WEEK(finalDate);
    IF(weekNumberEndDate != weekNumberStartDate) THEN
        set weekDiff = (weekNumberEndDate - weekNumberStartDate) * 2;
        set finalDate = DATE_ADD(finalDate, INTERVAL weekDiff DAY);
    END IF;
    
    IF(WEEKDAY(finalDate) IN (5, 6)) THEN
        set finalDate = DATE_ADD(finalDate, INTERVAL 2 DAY);
    END IF;
    
    
return finalDate;
END$$
DELIMITER ;

基本上,我使用与接受的答案相同的逻辑,但累积了周末。因此,对于每个周末,我将增加2天,如果结果日期在周末,我将增加2天

答案 5 :(得分:0)

使用 recursive CTE 可以在任意天数内轻松完成此操作:

WITH RECURSIVE a AS (
    SELECT
        CURRENT_DATE date,  -- Start date
        0 days
    UNION
    SELECT
        -- Always increment the date
        a.date + INTERVAL 1 DAY AS date,
        -- Increment the work day count only if it's not a weekend day
        a.days + (WEEKDAY(a.date + INTERVAL 1 DAY) < 5) AS days
    FROM a
    WHERE
        -- Keep going until the week day count reaches 10
        a.days < 10  -- Amount of days to add
)
SELECT MAX(date)
FROM a

在示例情况下,您将使用子查询:

SELECT
    (
        WITH RECURSIVE a AS (
            SELECT
                date_field date,
                0 days
            UNION
            SELECT
                a.date + INTERVAL 1 DAY AS date,
                a.days + (WEEKDAY(a.date + INTERVAL 1 DAY) < 5) AS days
            FROM a
            WHERE a.days < 5
        )
        SELECT MAX(date)
        FROM a
    ) AS final_date
FROM table_name

答案 6 :(得分:-1)

WHERE datefield BETWEEN CURRENT_DATE AND CURRENT_DATE + INTERVAL 7 DAY
AND WEEKDAY(datefield) NOT IN (5,6);