2011-01-22 60 views
1

我确定有人已经开发出了在其他编程语言中模拟Excel网络日功能的工作。如果你可以分享的话,你可以选择 。 感谢在sql中模拟Excel networkdays

+0

[MySQL的函数的可能的复制找到工作日内两个日期之间的数](http://stackoverflow.com/questions/1828948/mysql-function-to-find-the-number-of-working-days-between-two-dates) – 2017-04-21 18:48:51

回答

3

的想法是计算每个日期的星期然后采用各种偏移的开始之间的工作日。

  1. 每个日期前找到周六之间的天数
  2. 除以7乘以5得到的工作日数
  3. 偏移总的起始日期是否是结尾日期
  4. 再次偏移量开始是否结束后开始是星期六
  5. 再次为启动是否是后到底是星期天
  6. 再次为启动以后是否不和开始是一个星期天
  7. 为再次启动后,是否不和,到底是周六

添加一些随机的日期到表中。

declare @t table ([start] datetime, [end] datetime) 
insert into @t values ('2088-01-14 11:56:23','2011-11-10 03:34:09') 
insert into @t values ('2024-09-24 10:14:29','2087-09-16 15:52:06') 

然后为这些日期计算NETWORKDAYS。

select [start],[end] 
    ,((datediff(day,0,[end])-datepart(dw,[end]))-(datediff(day,0,[start])-datepart(dw,[start])))/7*5 --[weekdays] 
    + datepart(dw,[end]) - datepart(dw,[start]) --[weekday diff] 
    + case when datediff(day,0,[start]) > datediff(day,0,[end]) then -1 else 1 end --[start after] 
    + case when datediff(day,0,[start]) > datediff(day,0,[end]) and datepart(dw,[start]) = 7 then 1 else 0 end --[start after and start saturday] 
    + case when datediff(day,0,[start]) > datediff(day,0,[end]) and datepart(dw,[end]) = 1 then 1 else 0 end --[start after and end sunday] 
    + case when datediff(day,0,[start]) <= datediff(day,0,[end]) and datepart(dw,[start]) = 1 then -1 else 0 end --[start not after and start sunday] 
    + case when datediff(day,0,[start]) <= datediff(day,0,[end]) and datepart(dw,[end]) = 7 then -1 else 0 end --[start not after and end saturday] 
    as [networkdays] 
    from @t 
+2

欢迎来到Stack Overflow!在答案中提供至少一个简短的解释和代码是一个好主意。 – Techwolf 2012-11-08 06:32:03

0

对于它的价值,我创建了以下功能的MySQL,它假定周一至周五的工作日:

DROP FUNCTION IF EXISTS BusinessDays; 

DELIMITER // 

CREATE FUNCTION BusinessDays (startDate DATE, endDate DATE) 
RETURNS INT 
DETERMINISTIC 
BEGIN 
    DECLARE startWeekDay INT; 
    DECLARE allDays INT; 
    DECLARE fullWeekCount INT; 
    DECLARE remainderDays INT; 
    DECLARE maxPossibleRemainderWeekendDays INT; 
    DECLARE soloSundays INT; 
    DECLARE totalBusinessDays INT; 

    SET startWeekDay = WEEKDAY(startDate); 
    SET allDays = ABS(DATEDIFF(endDate, startDate)) + 1; 
    SET fullWeekCount = FLOOR(allDays/7); 
    SET remainderDays = allDays - (fullWeekCount * 7); 
    SET maxPossibleRemainderWeekendDays = ROUND(2*(startWeekDay+remainderDays-6)/(ABS(2*(startWeekDay+remainderDays-6))+1))+1; 
    SET soloSundays = ROUND(2*(startWeekDay-6)/(ABS(2*(startWeekDay-6))+1))+1; 

    SET totalBusinessDays = allDays - (fullWeekCount * 2) - maxPossibleRemainderWeekendDays + soloSundays; 
    RETURN totalBusinessDays; 
END // 

DELIMITER ;