【问题标题】:Simulating NETWORKDAYS returns wrong business days模拟 NETWORKDAYS 返回错误的工作日
【发布时间】:2019-06-30 18:27:45
【问题描述】:

我在基于this solution 的 sql 上创建了一个类似 NETWORKDAYS 的函数,它可以正确返回工作日,而记录(BEG 和 END)在工作日

BEG        END         businessd
--------------------------------
01/01/2018 15/01/2018  10       

--(15 days total)-(1st jan)-(4 weekends) = 10 | correct result

但在某些情况下,如果 BEG 或 END 被“存储”在周末,它会计算额外的天数:

BEG        END         businessd
--------------------------------
01/01/2018 28/01/2018  20       

--(28 days total)-(1st jan)-(4 weekends) = 19 | incorrect result

我的代码在BEGFIN 之间执行datediff,并减去存储在holydays 表中的周末和圣日

    SELECT e.*, 
            DATEDIFF(DAY, cast(BEG as datetime), cast(FIN as datetime))+1 --sum end date day
              -(SELECT
               (DATEDIFF(WK, cast(BEG as datetime), cast(FIN as datetime)) )
              +(CASE WHEN DATENAME(dw, cast(BEG as datetime)) = 'Sunday' THEN 1 ELSE 0 END)
              +(CASE WHEN DATENAME(dw, cast(FIN as datetime)) = 'Saturday' THEN 1 ELSE 0 END)
            ) * 2
            -(SELECT COUNT(*) FROM holydays nl
             WHERE nl.FECHA BETWEEN cast(BEG as datetime) AND cast(FIN as datetime)
            ) AS businessd,

            convert(nvarchar(6),cast(BEG as datetime),112) as iddate --new id based on fin
    FROM e
    ORDER BY original_ini,BEG

我该如何处理这些情况才能正确计算工作日?

【问题讨论】:

    标签: sql sql-server-2008 datediff


    【解决方案1】:

    您可以为此目的使用日历表。有了它,这个操作会很简单。

    你甚至可以处理银行假期

    Check Thisthis (Calendar Table)

    select * from calendar where isWorkDay = 1  
    

    会给你工作日,然后你可以像这样简单地加入

    select * from t
    where exists 
    ( select 1 from calendar where isWorkDay = 1 and calendar.dt betweenn t.beg and t.end) 
    

    【讨论】:

    • 嘿,很抱歉这么晚才回答,我使用您的链接从头开始创建了一个表格,但您的 JOIN 似乎不起作用。使用calendar.dt时叫什么?
    • 你需要使用Calendar.CalendarDate
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-12
    • 2020-09-26
    • 2023-03-26
    • 2022-01-23
    • 2023-01-03
    • 1970-01-01
    相关资源
    最近更新 更多