使用SSMS计算不包括周末,假日和非工作时间的小时数[重复]

问题描述 投票:0回答:1

这个问题在这里已有答案:

首先,我想说我是SSMS的新手,所以如果有些事情不完全清楚,请耐心等待。所以这是我的问题。

我想在工作时间内计算2个日期的时间,它应该排除周末和假日。

我找到了一个函数脚本,它计算了工作时间内的时间,并确实排除了周末。现在我错过了排除假期的部分。我制作了一张假期表,其中包含假期的名称和日期。

我找到了另一个计算没有假期的时间的函数,但是当我用它运行查询时,我得到的输出太多了。而且我不确定会出现什么问题。

这是我正在使用的新功能,它提供了太多的输出。

CREATE FUNCTION getWorkingHoursDiff(
@startDate datetime,
@endDate datetime)
RETURNS int AS
BEGIN

    DECLARE @totaldays INT; 
    DECLARE @weekenddays INT;    

    DECLARE @ShiftStartOn datetime, @ShiftEndOn datetime
    Declare @startHourDiff int, @endHourDiff int

    set @ShiftStartOn = cast(CONVERT(VARCHAR,@startDate,110)+' 08:00' as Datetime)
    set @ShiftEndOn = cast(CONVERT(VARCHAR, @endDate,110)+' 18:00' as Datetime)

    declare @ShiftHours int
    set @ShiftHours = DATEDIFF(HOUR, @ShiftStartOn, @ShiftEndOn)

    set @startHourDiff = 0

    if @startDate between @ShiftStartOn and DATEADD(hour, @ShiftHours, @ShiftStartOn)
    begin
        set @startHourDiff = DATEDIFF(HOUR, @ShiftStartOn, @startDate)    
        set @startDate = @ShiftStartOn

        if(@startHourDiff < 0)    
        begin        
            set @startHourDiff = 0    
        end        
    end
    if DATEPART(WEEKDAY, @startDate) = 1 or DATEPART(WEEKDAY, @startDate) = 7
        set @startHourDiff = 0

    if exists(select 1 from table_holiday where DATEDIFF(day, start_time, @startDate) = 0)
        set @startHourDiff = 0    

    if @startDate > DATEADD(hour, @ShiftHours, @ShiftStartOn)
        set @startDate = DATEADD(day,1,@ShiftStartOn)    

    set @endHourDiff = 0    
    if @endDate between DATEADD(hour, -@ShiftHours, @ShiftEndOn) and @ShiftEndOn
    begin
        set @endHourDiff = DATEDIFF(HOUR, @endDate, @ShiftEndOn)            

        set @endDate = @ShiftEndOn

        if(@endHourDiff < 0)
            set @endHourDiff = 0    
    end
    if DATEPART(WEEKDAY, @endDate) = 1 or DATEPART(WEEKDAY, @endDate) = 7
        set @endHourDiff = 0

    if exists(select 1 from table_holiday where DATEDIFF(day, start_time, @endDate) = 0)
        set @endHourDiff = 0

    if @endDate < DATEADD(hour, -@ShiftHours, @ShiftEndOn)
        set @endDate = DATEADD(day,-1,@ShiftEndOn)

    SET @totaldays = DATEDIFF(DAY, @startDate, @endDate) +1     

    SET @weekenddays = ((DATEDIFF(WEEK, @startDate, @endDate) * 2) + -- get the number of weekend days in between
                       CASE WHEN DATEPART(WEEKDAY, @startDate) = 1 THEN 1 ELSE 0 END + -- if selection was Sunday, won't add to weekends
                       CASE WHEN DATEPART(WEEKDAY, @endDate) = 7 THEN 1 ELSE 0 END)  -- if selection was Saturday, won't add to weekends

    select @totaldays = @totaldays - @weekenddays

    declare @chkdtFromDate datetime, @chkdtToDate datetime

    select @chkdtFromDate =  DATEADD(dd, DATEDIFF(dd, 0, @startDate), 0)
    select @chkdtToDate =  DATEADD(dd, DATEDIFF(dd, 0, @endDate), 0)

    select @totaldays = @totaldays - COUNT(1) from table_holiday where (start_time between @chkdtFromDate and @chkdtToDate)

    return (@totaldays*@ShiftHours) - @startHourDiff - @endHourDiff
End
Go

这将显示我添加的两个函数的输出。第一个函数在结果中看起来非常精细。但它并不排除假期。

你看到的第二个结果给出了更多的小时,如OpenstaandeTijdInUren列所示,而它应该为我提供10小时的值,因为05-30是假期。

enter image description here

sql sql-server tsql ssms
1个回答
0
投票

找工作日,下面是愚蠢的例子

declare @begin datetime2 = getdate() - .1
declare @end datetime2 = getdate() + .1
select 
    case when datepart(dw, @begin) in (2,3,4,5,6) and datepart(dw, @end) in (2,3,4,5,6) then rtrim(datediff(hour, @begin, @end)) + ' hours' else 'Weekend! Go Home!' end 
© www.soinside.com 2019 - 2024. All rights reserved.