2013-03-18 2 views
0

Распространяя этот вопрос: Hereдней Количества работы между двумя датами в T-SQL (Extended)

Я хотел бы рассчитывать рабочие дни между двумя датами в T-SQL, только в выходные дни, но не весь рабочий день (24 hrs), скажем так, с 9 утра до 5:30 вечера каждый рабочий день.

Как я могу это сделать с помощью, например CMS 'подхода:

DECLARE @StartDate DATETIME 
DECLARE @EndDate DATETIME 
SET @StartDate = '2008/10/01' 
SET @EndDate = '2008/10/31' 


SELECT 
    (DATEDIFF(dd, @StartDate, @EndDate) + 1) 
    -(DATEDIFF(wk, @StartDate, @EndDate) * 2) 
    -(CASE WHEN DATENAME(dw, @StartDate) = 'Sunday' THEN 1 ELSE 0 END) 
    -(CASE WHEN DATENAME(dw, @EndDate) = 'Saturday' THEN 1 ELSE 0 END) 

ответ

0

Это то, что я искал, вот код, в случае, если кто-то это нужно:

Параметры:

@D1 (StartDate) 
@D2 (EndDate) 
@T1 (Business Hours - Start) 
@T2 (Business Hours - End) 

Функция возвращает поплавок с количеством часов.


CREATE FUNCTION [dbo].[WorkHoursDiff] (@D1 as datetime,@D2 as datetime,@T1 as int,@T2 as int) 
RETURNS float AS 
BEGIN 
    if @D1>@D2 return 0 

    declare @whd as float 

    declare @H1 as float 
    declare @H2 as float 


    if not (datepart(yyyy,@D1 )=datepart(yyyy,@D2) and datepart(mm,@D1)=datepart(mm,@D2) and datepart(dd,@D1)=datepart(dd,@D2)) 
     begin 
      declare @DD as datetime 
      SET @whd=0 
      if datepart(dw,@D1)<>1 and datepart(dw,@D1)<>7 
             if dbo.GetDateHour(@D1)<@T1 SET @whd = @[email protected] 
      else if dbo.GetDateHour(@D1)>@T2 SET @whd = 0 
      else if dbo.GetDateHour(@D1)>[email protected] and dbo.GetDateHour(@D1)<[email protected] SET @whd = @T2-dbo.GetDateHour(@D1) 

      SET @[email protected] + 1 
      while not (datepart(yyyy,@DD)=datepart(yyyy,@D2) and datepart(mm,@DD)=datepart(mm,@D2) and datepart(dd,@DD)=datepart(dd,@D2)) 
       begin 
        if not(datepart(dw,@DD)=1 or datepart(dw,@DD)=7) 
         SET @[email protected] + (@[email protected]) 

        SET @[email protected] + 1 
       end 
       if datepart(dw,@D2)<>1 and datepart(dw,@D2)<>7 
       if dbo.GetDateHour(@D2)<@T1 SET @whd = @whd 
       else if dbo.GetDateHour(@D2)>@T2 SET @whd = @whd + @T2 - @T1 
       else if dbo.GetDateHour(@D2)>[email protected] and dbo.GetDateHour(@D2)<[email protected] SET @whd = @whd +dbo.GetDateHour(@D2)[email protected] 

     end 
    else 
     begin 
      if dbo.GetDateHour(@D1)<@T1 SET @[email protected] 
      else if dbo.GetDateHour(@D1)>@T2 SET @[email protected] 
      else SET @H1=dbo.GetDateHour(@D1) 

      if dbo.GetDateHour(@D2)<@T1 SET @[email protected] 
      else if dbo.GetDateHour(@D2)>@T2 SET @[email protected] 
      else SET @H2=dbo.GetDateHour(@D2) 

      if datepart(dw,@D1)=1 or datepart(dw,@D1)=7 SET @whd=0 
      else SET @[email protected]@H1 
     end 
    return @whd 

END 
1

Я думаю, что вы очень хорошо было это, просто нужно изменить ТОГДА 1 к ТОГДА -1

Однако, я m не совсем уверен, что вы хотели бы сделать с часами части вашего вопроса.

DECLARE @StartDate DATETIME 
DECLARE @EndDate DATETIME 
SET @StartDate = '2013/03/01' 
SET @EndDate = '2013/03/31' 


SELECT 
    (DATEDIFF(dd, @StartDate, @EndDate) + 1) 
    -(DATEDIFF(wk, @StartDate, @EndDate) * 2) 
    -(CASE WHEN DATENAME(dw, @StartDate) = 'Sunday' THEN -1 ELSE 0 END) 
    -(CASE WHEN DATENAME(dw, @EndDate) = 'Saturday' THEN -1 ELSE 0 END) 
+0

рабочего времени часть бизнес часов рабочего дня. В этом случае мне придется менять датифф в часах вместо дней. Предположим, что я хочу узнать рабочее время между двумя датами в понедельник и вторник, с вышеупомянутым решением у меня будет 48 часов (2 дня), но с рабочими часами (с 9 утра до 5 вечера) будет 16 часов, вот что мне нужно , – Somebody

0

нашел это ..

CREATE FUNCTION dbo.GetWorkingDays 
    (@StartDate datetime, 
    @EndDate datetime) 
RETURNS INT 
AS 
BEGIN 
    DECLARE @WorkDays int, @FirstPart int 
    DECLARE @FirstNum int, @TotalDays int 
    DECLARE @LastNum int, @LastPart int 
    IF (DATEDIFF(day, @StartDate, @EndDate) < 2) 
    BEGIN 
     RETURN (0) 
    END 
    SELECT 
    @TotalDays = DATEDIFF(day, @StartDate, @EndDate) - 1, 
    @FirstPart = CASE DATENAME(weekday, @StartDate) 
       WHEN 'Sunday' THEN 6 
       WHEN 'Monday' THEN 5 
       WHEN 'Tuesday' THEN 4 
       WHEN 'Wednesday' THEN 3 
       WHEN 'Thursday' THEN 2 
       WHEN 'Friday' THEN 1 
       WHEN 'Saturday' THEN 0 
       END, 
    @FirstNum = CASE DATENAME(weekday, @StartDate) 
       WHEN 'Sunday' THEN 5 
       WHEN 'Monday' THEN 4 
       WHEN 'Tuesday' THEN 3 
       WHEN 'Wednesday' THEN 2 
       WHEN 'Thursday' THEN 1 
       WHEN 'Friday' THEN 0 
       WHEN 'Saturday' THEN 0 
       END 
    IF (@TotalDays < @FirstPart) 
    BEGIN 
     SELECT @WorkDays = @TotalDays 
    END 
    ELSE 
    BEGIN 
     SELECT @WorkDays = (@TotalDays - @FirstPart)/7 
     SELECT @LastPart = (@TotalDays - @FirstPart) % 7 
     SELECT @LastNum = CASE 
     WHEN (@LastPart < 7) AND (@LastPart > 0) THEN @LastPart - 1 
     ELSE 0 
     END 
     SELECT @WorkDays = @WorkDays * 5 + @FirstNum + @LastNum 
    END 
    RETURN (@WorkDays) 
END 
GO 
Смежные вопросы