【问题标题】:Calculating NETWORKDAYS using a CalendarTable SQL Server 2008使用 CalendarTable SQL Server 2008 计算 NETWORKDAYS
【发布时间】:2019-07-05 09:48:20
【问题描述】:

之前我创建了一个 SELECT 来计算工作日(周末/节假日),这对于每条记录的某些日期范围不起作用。有人建议我使用日历表,它实际上适用于我搁置的其他要求,但我不知道如何计算工作日的 INIEND

我尝试使用半左连接和连接(也建议)进行 SELECT,但它似乎根本无法计算。

这是日历表:

CalendarId  DateValue               DayNumberOfWeek NameOfDay  NameOfMonth WeekOfYear  JulianDay   USAIsBankHoliday USADayName
----------- ----------------------- --------------- ---------- ----------- ----------- ----------- ---------------- -------------------
20100101    2010-01-01 00:00:00.000 5               Viernes    Enero       1           1           1                Año nuevo

我的桌子:

INI                            FIN                            DD --DATEDIFF BETWEEN DATES
------------------------------ ------------------------------ -----------
20180129                       20180211                       14

我尝试计算工作日

SELECT CONVERT(NVARCHAR,INI,112) AS INI, 
    CONVERT(NVARCHAR,FIN,112) AS FIN, 
    DATEDIFF(DD, INI, FIN)+1 AS DD 
FROM HISTORICOLICMED T
WHERE EXISTS(
    SELECT 1 FROM CALENDAR C
    WHERE T.INI = C.CALENDARID and T.FIN = C.CALENDARID
    AND C.USAISBANKHOLIDAY = 0 BETWEEN T.INI AND T.FIN)

我希望得到正确的工作日计算,包括假期,所以对于上面的例子,我会得到类似的结果:

INI                            FIN                            DD     ND
------------------------------ ------------------------------ ----- -----
20180129                       20180211                       14     10

【问题讨论】:

  • 你的表不能有两个名为INI的列。

标签: sql sql-server sql-server-2008 datediff


【解决方案1】:

建议的解决方案:

set datefirst 1;
select INI
    ,FIN
    , DATEDIFF(DD, INI, FIN)+1 as DD
    ,(DATEDIFF(DD, INI, FIN)+1)
    -(DATEDIFF(WK, INI, FIN)*2)
    -(case DATEPART(DW, INI)    when 7 then 1 else 0 end)
    -(case DATEPART(DW, FIN)    when 6 then 1 else 0 end)
    -(select COUNT(*) from CALENDAR
        where DateValue between INI and FIN
        and USAIsBankHoliday = 1)
    as ND -- Working days except US Bank holidays
from HISTORICOLICMED;

【讨论】:

    【解决方案2】:

    子选择日历表中位于INIFIN 之间且为工作日的行数。

    SELECT CONVERT(NVARCHAR,INI,112) AS INI, 
        CONVERT(NVARCHAR,FIN,112) AS FIN, 
        DATEDIFF(DD, INI, FIN)+1 AS DD, 
        (SELECT COUNT(*) FROM CalendarTable WHERE ...) AS ND
    FROM HISTORICOLICMED 
    

    【讨论】:

    • 子选择 USABANKHOLIDAYS 不会显示非工作日。 SELECT CONVERT(NVARCHAR,INI,112) AS INI, CONVERT(NVARCHAR,FIN,112) AS FIN, DATEDIFF(DD, INI, FIN)+1 AS DD FROM HISTORICOLICMED T WHERE EXISTS ( SELECT COUNT(USAISBANKHOLIDAY) AS D FROM CALENDAR C WHERE C.CALENDARID BETWEEN T.INI AND T.FIN )
    • 不,根本不要使用 EXISTS。使您的第四列成为子选择。查看我的编辑。
    • 我无法转换 INI 或 FIN,因为我得到了 Msg 8115,即使我将其转换为其他数据类型,如 int 或 varchar(我猜是因为 CALENDARID 是 int?)跨度>
    • CalendarID BETWEEN INI and FIN代替DateValue
    猜你喜欢
    • 1970-01-01
    • 2011-04-11
    • 1970-01-01
    • 2023-04-08
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多