Подтвердить что ты не робот

Получить DATEDIFF, исключая выходные дни, используя сервер sql

Я использую этот запрос, чтобы получить время.

SELECT DATEDIFF(dd, ActualStartDate, ActualCompletionDate) AS TimeTaken
FROM TableName

Теперь я хочу исключить выходные и включать только пн-пт в считанные дни.

4b9b3361

Ответ 1

Пример ниже, вот некоторые подробности о том, как я его решил.

Использование DATEDIFF(WK, ...) даст нам количество недель между двумя датами. SQL Server оценивает это как разницу между номерами недель, а не в зависимости от количества дней. Это прекрасно, так как мы можем использовать это, чтобы определить, сколько уикэндов прошло между датами.

Итак, мы можем умножить это значение на 2, чтобы получить количество дней выходных дней, которые произошли, и вычесть это из DATEDIFF(dd, ...), чтобы получить количество будних дней.

Это не ведет себя на 100% правильно, если дата начала или окончания падает в воскресенье. Поэтому я добавил в некоторых случаях логику в конце вычисления для обработки этих экземпляров.

Вы также можете рассмотреть вопрос о том, должен ли DATEDIFF быть полностью включенным. например Разница между 9/10 и 9/11 1 день или 2 дня? Если последний, вы хотите добавить 1 в конечный продукт.

declare @d1 datetime, @d2 datetime
select @d1 = '9/9/2011',  @d2 = '9/18/2011'

select datediff(dd, @d1, @d2) - (datediff(wk, @d1, @d2) * 2) -
       case when datepart(dw, @d1) = 1 then 1 else 0 end +
      case when datepart(dw, @d2) = 1 then 1 else 0 end

Ответ 2

Я обнаружил, что когда я использовал это, возникла проблема, когда d1 упал в субботу. Ниже я исправлю это.

declare @d1 datetime, @d2 datetime
select @d1 = '11/19/2011' ,  @d2 = '11/28/2011'

select datediff(dd, @d1, @d2) +case when datepart(dw, @d1) = 7 then 1 else 0 end - (datediff(wk, @d1, @d2) * 2) -
 case when datepart(dw, @d1) = 1 then 1 else 0 end +
 case when datepart(dw, @d2) = 1 then 1 else 0 end

Ответ 3

BEGIN 
DECLARE @totaldays INT; 
DECLARE @weekenddays INT;

SET @totaldays = DATEDIFF(DAY, @startDate, @endDate) 
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) = 6 THEN 1 ELSE 0 END)  -- if selection was Saturday, won't add to weekends

Return (@totaldays - @weekenddays)

END

Это на SQL Server 2014

Ответ 4

declare @d1 datetime, @d2 datetime
select @d1 = '4/19/2017',  @d2 = '5/7/2017'

DECLARE @Counter int = datediff(DAY,@d1 ,@d2 )

DECLARE @C int = 0
DECLARE @SUM int = 0





 WHILE  @Counter > 0
  begin
 SET @SUM = @SUM + IIF(DATENAME(dw, 

 DATEADD(day,@c,@d1))IN('Sunday','Monday','Tuesday','Wednesday','Thursday')
 ,1,0)



SET @Counter = @Counter - 1
set @c = @c +1
end

select @Sum

Ответ 5

Я просто хочу поделиться созданным мной кодом, который может вам помочь.

DECLARE @MyCounter int = 0, @TempDate datetime, @EndDate datetime;
SET @TempDate = DATEADD(d,1,'2017-5-27')
SET @EndDate = '2017-6-3'

WHILE @TempDate <= @EndDate
    BEGIN
    IF DATENAME(DW,@TempDate) = 'Sunday' OR DATENAME(DW,@TempDate) = 'Saturday'
        SET @MyCounter = @MyCounter
    ELSE IF @TempDate not in ('2017-1-1', '2017-1-16', '2017-2-20', '2017-5-29', '2017-7-4', '2017-9-4', '2017-10-9', '2017-11-11', '2017-12-25')
        SET @MyCounter = @MyCounter + 1

    SET @TempDate = DATEADD(d,1,@TempDate)
    CONTINUE

END
PRINT @MyCounter
PRINT @TempDate

Если у вас есть праздничная таблица, вы также можете использовать ее так, чтобы вам не приходилось перечислять все праздники в секции ELSE IF кода. Вы также можете создать функцию для этого кода и использовать эту функцию, когда вам это нужно в вашем запросе.

Надеюсь, это тоже поможет.

Ответ 6

Используя fooobar.com/info/103608/... и ответ JeffFisher30 выше (fooobar.com/info/257741/...), и моя собственная необходимость иметь дробных дней, я написал это:

DateDiff(second,Start_Time,End_Time)/86400.0
            -2*DateDiff(week, Start_Time, End_Time)
            -Case When (DatePart(weekday, Start_Time)[email protected]@DateFirst)%7 = 1 Then 1 Else 0 End
            +Case When (DatePart(weekday, End_Time)[email protected]@DateFirst)%7 = 1 Then 1 Else 0 End