我确信有人已经尝试用其他编程语言模拟Excel networkdays功能。 如果你可以分享,那就是aprriciate。 谢谢
答案 0 :(得分:3)
我们的想法是计算每个日期周开始之间的工作日,然后应用各种补偿。
在表格中添加一些随机日期。
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
答案 1 :(得分:1)
根据SO问题"Equivalent of Excel’s NETWORKDAYS function with Jet ADO"
的SQL解决方案答案 2 :(得分:1)
希望这可以帮助某个人,但这对我有用。需要您创建dbo.FederalHolidays表(可以使用在线日期源轻松填充该表)。 我想出的最简洁的方法很容易扩展。
return !string.IsNullOrEmpty(webBrowser.Document.GetElementById("uiDynamicText").InnerText);
答案 3 :(得分: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 ;
答案 4 :(得分:0)
也许这也会有所帮助,我创建了一个模拟NETWORKDAYS函数的公式(在Excel中):
= 1 + ( ( B1 - A1) * 5 - ( WEEKDAY(A1) - WEEKDAY(B1) ) * 2 ) / 7 + IF(A1<=B1,IF(WEEKDAY(B1)=7,-1,0) + IF(WEEKDAY(A1)=1,-1,0), IF(WEEKDAY(B1)<>1,-1,0) + IF(WEEKDAY(A1)<>7,-1,0) )
注意:WEEKDAY()
星期日为0
星期六为6
答案 5 :(得分:0)
我一直在寻找这种功能,所以继续并自行创建了它。
用法:这是您可以在SQL中创建的函数。您可以轻松地对此进行修改,以在需要时在函数外部工作,但是我更喜欢函数来处理这些类型的计算。
我添加了很多评论,以防有人怀疑它是如何工作的。这需要两个输入:
计算过程: 重复循环直到达到工作天数。例如,如果输入365天,它将循环大约500次,然后才能预测要添加的工作日数。我添加了@weekendCount,以防有人在到达最终结束日期之前需要知道排除的周末数。
完成后,整数@recCounter本质上是达到工作天数之前必须添加到@startDate的天数。我确信有人可以比我写得更好,或者有人可以利用它。希望这可以帮助! :)
CREATE FUNCTION [dbo].[addNetworkDays](@startDate AS DATETIME, @addDays AS Int)
RETURNS DATETIME
AS
BEGIN
DECLARE @recCounter Int
SET @recCounter = 0
DECLARE @weekendCount Int
SET @weekendCount = 0
DECLARE @workdayCount Int
SET @workdayCount = 0
DECLARE @newDate DateTime
WHILE @addDays > @workdayCount
BEGIN
-- Add another day to the start date
SET @recCounter = @recCounter + 1
-- Cumuluate the weekend vs. workday counter, based on the day of the week. This loop will repeat until @workdayCount has reached the @addDays.
-- Note that @weekendCount is not used in any capacity, can be used if you need to know how many weekend days there are.
IF DATEPART(dw, DATEADD(d, @recCounter, @startDate)) IN (1, 7) SET @weekendCount = @weekendCount + 1
IF DATEPART(dw, DATEADD(d, @recCounter, @startDate)) IN (2, 3, 4, 5, 6) SET @workdayCount = @workdayCount + 1
END
-- At this point, the script has completed the cycle, stopping when the detected # of workdays has reached the count of days the user specified.
-- Calculate the new date, based on the # of cycles *days* detected above.
SET @newDate = DATEADD(d, @recCounter, @startDate)
-- If the new/adjusted date falls on a Saturday or Sunday, add additional days to compensate.
IF DATEPART(dw, @newDate) = 1 SET @newDate = DATEADD(d, 1, @newDate)
IF DATEPART(dw, @newDate) = 7 SET @newDate = DATEADD(d, 1, @newDate)
RETURN CAST(@newDate AS DATETIME)
答案 6 :(得分:0)
澳大利亚的NETWORKDAYS
WITH PH_NET_WORKDAY AS
(
----BUILD UNDERLYING WORKDAY DATA TABLE
SELECT
DT,
STATE,
CASE
WHEN WORKDAY-PUBLIC_HOLIDAY <0
THEN 0
ELSE WORKDAY-PUBLIC_HOLIDAY
END AS WORKDAY
FROM
(
SELECT
DT,
STATE,
WORKDAY,
----PUBLIC HOLIDAY INFORMATION HERE
CASE
WHEN STATE = 'NSW'
THEN
CASE
WHEN DT IN (
'01-Oct-2018',
'25-Dec-2018',
'26-Dec-2018',
'01-Jan-2019',
'28-Jan-2019',
'19-Apr-2019',
'20-Apr-2019',
'21-Apr-2019',
'22-Apr-2019',
'25-Apr-2019',
'10-Jun-2019',
'07-Oct-2019',
'25-Dec-2019',
'26-Dec-2019'
)
THEN 1
ELSE 0
END
WHEN STATE = 'SA'
THEN
CASE
WHEN DT IN (
'01-Oct-2018',
'24-Dec-2018',
'25-Dec-2018',
'26-Dec-2018',
'31-Dec-2018',
'01-Jan-2019',
'28-Jan-2019',
'11-Mar-2019',
'19-Apr-2019',
'20-Apr-2019',
'22-Apr-2019',
'25-Apr-2019',
'10-Jun-2019',
'07-Oct-2019',
'24-Dec-2019',
'25-Dec-2019',
'26-Dec-2019'
)
THEN 1
ELSE 0
END
WHEN STATE = 'QLD'
THEN
CASE
WHEN DT IN (
'01-Oct-2018',
'25-Dec-2018',
'26-Dec-2018',
'01-Jan-2019',
'28-Jan-2019',
'19-Apr-2019',
'20-Apr-2019',
'21-Apr-2019',
'22-Apr-2019',
'25-Apr-2019',
'06-May-2019',
'07-Oct-2019',
'25-Dec-2019',
'26-Dec-2019'
)
THEN 1
ELSE 0
END
WHEN STATE = 'VIC'
THEN
CASE
WHEN DT IN (
'28-Sep-2018',
'06-Nov-2018',
'25-Dec-2018',
'26-Dec-2018',
'01-Jan-2019',
'28-Jan-2019',
'11-Mar-2019',
'19-Apr-2019',
'20-Apr-2019',
'21-Apr-2019',
'22-Apr-2019',
'25-Apr-2019',
'10-Jun-2019',
'05-Nov-2019',
'25-Dec-2019',
'26-Dec-2019'
)
THEN 1
ELSE 0
END
WHEN STATE = 'TAS'
THEN
CASE
WHEN DT IN (
'25-Dec-2018',
'26-Dec-2018',
'01-Jan-2019',
'28-Jan-2019',
'11-Mar-2019',
'19-Apr-2019',
'22-Apr-2019',
'23-Apr-2019',
'25-Apr-2019',
'10-Jun-2019',
'25-Dec-2019',
'26-Dec-2019'
)
THEN 1
ELSE 0
END
ELSE 0
END AS PUBLIC_HOLIDAY
FROM
(
SELECT
DT.*,
ST.*
FROM
(
SELECT
TRUNC (TO_DATE('01-JAN-2021','DD-MON-YYYY') - ROWNUM) AS DT,
TRIM(TO_CHAR( TRUNC (TO_DATE('01-JAN-2021','DD-MON-YYYY') - ROWNUM) , 'DAY')) AS WEEK_DAY,
CASE
WHEN TRIM(TO_CHAR( TRUNC (TO_DATE('01-JAN-2021','DD-MON-YYYY') - ROWNUM) , 'DAY')) = 'SATURDAY'
THEN 0
WHEN TRIM(TO_CHAR( TRUNC (TO_DATE('01-JAN-2021','DD-MON-YYYY') - ROWNUM) , 'DAY')) = 'SUNDAY'
THEN 0
----BUILD STATE PUBLIC HOLIDAY DATE SET HERE, WE CAN EXCLUDE PUBLIC HOLIDAYS
ELSE 1
END AS WORKDAY
FROM DUAL CONNECT BY ROWNUM < (365.25*8+1)
) DT
,
(
SELECT 'NSW' AS STATE FROM DUAL
UNION
SELECT 'QLD' AS STATE FROM DUAL
UNION
SELECT 'SA' AS STATE FROM DUAL
UNION
SELECT 'ACT' AS STATE FROM DUAL
UNION
SELECT 'VIC' AS STATE FROM DUAL
UNION
SELECT 'ACT' AS STATE FROM DUAL
) ST
)
)
),
----A SAMPLE DATA SET FOR SAME DATES BETWEEN DIFFERENT STATE TO TEST PUBLIC HOLIDAY DIFFERENCES
SAMPLE_DATA AS
(
SELECT
'01-FEB-2019' AS D1,
'11-FEB-2019' AS D2,
'NSW' AS STATE
FROM DUAL
UNION
SELECT
'01-FEB-2019' AS D1,
'11-FEB-2019' AS D2,
'SA' AS STATE
FROM DUAL
UNION
SELECT
'19-APR-2019' AS D1,
'26-APR-2019' AS D2,
'NSW' AS STATE
FROM DUAL
)
----SELECT WORKDAYS FROM PH TABLE AND INSERT INTO SAPLE TABLE
SELECT
SAMPLE_DATA.*,
(
SELECT SUM(WORKDAY)
FROM PH_NET_WORKDAY
WHERE
STATE = SAMPLE_DATA.STATE
AND DT>=SAMPLE_DATA.D1
AND DT<=SAMPLE_DATA.D2
)
AS WORKDAYS
FROM SAMPLE_DATA