我想在提供的日期添加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
答案 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`;
工作原理:
date_field
和5天后的两个星期相同时,必须再添加2天。Sat
或Sun
,必须再添加2天。答案 1 :(得分:0)
试试这个,应该很好地工作,基本上循环每一天并检查它们是星期六还是星期天,忽略它们。
答案 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);