Получить DATEDIFF, исключая выходные дни, используя сервер sql
Я использую этот запрос, чтобы получить время.
SELECT DATEDIFF(dd, ActualStartDate, ActualCompletionDate) AS TimeTaken
FROM TableName
Теперь я хочу исключить выходные и включать только пн-пт в считанные дни.
Ответы
Ответ 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