Tsql DATEDIFF仅限工作时间和天数
我试图写一份报告,但有点卡住了:/我试图显示两个日期之间的小时和分钟,但减去非工作时间 例如,一家公司在工作日的08:00到17:00之间工作,一个电话在今天的16:00被记录,明天的16:00结束,这将是24小时减去工作时间,因此将在9小时工作 我还创建了一个单独的表格,其中包含一年中除周末、工作日开始和工作日结束之外的所有日期。但我仍然要找出没有非营业时间的时间间隔 示例数据:Tsql DATEDIFF仅限工作时间和天数,tsql,datediff,Tsql,Datediff,我试图写一份报告,但有点卡住了:/我试图显示两个日期之间的小时和分钟,但减去非工作时间 例如,一家公司在工作日的08:00到17:00之间工作,一个电话在今天的16:00被记录,明天的16:00结束,这将是24小时减去工作时间,因此将在9小时工作 我还创建了一个单独的表格,其中包含一年中除周末、工作日开始和工作日结束之外的所有日期。但我仍然要找出没有非营业时间的时间间隔 示例数据: Call_Initiated - Call_Ended 10/05/2013 15:00 - 13/05/2013
Call_Initiated - Call_Ended
10/05/2013 15:00 - 13/05/2013 13:00
结果我想要
Call_Initiated - Call_Ended - Time_To_Resolve
10/05/2013 15:00 - 13/05/2013 13:00 - 07
我只是好奇你的问题,然后做了这个 也许不是最好的剧本,但它可能会给你一些解决问题的想法 它功能齐全,但我生成了日期,您可能希望使用day表
declare @callLogStart datetime = '2013-01-04 16:00'
declare @callLogEnd datetime = '2013-01-08 09:00'
;with dates(startDate, endDate)
as
(
select cast('2013-01-01 08:00' as datetime)
,cast('2013-01-01 17:00' as datetime)
union all
select DATEADD(day,1, startDate)
,DATEADD(day, 1, endDate)
from dates
where startDate < '2013-02-01 08:00'
)
,startDay
as
(
select *
,Datediff(hour, d.startDate, d.endDate) - DATEDIFF(hour, startDate, @callLogStart) as spent
from dates d
where @callLogStart between d.startDate and d.endDate
)
,endDay
as
(
select *
,Datediff(hour, d.startDate, d.endDate) - datediff(hour, @callLogEnd, endDate) as spent
from dates d
where @callLogEnd between d.startDate and d.endDate
)
select --SUM(spent) as actualTime
spent
,startDate
,endDate
,mark
from
(
select startDate
,endDate
,spent
,'start' as mark
from startDay
union
select startDate
,endDate
,spent
,'end'
from endDay
union
select s.startDate
,s.endDate
,-Datediff(hour, s.startDate, s.endDate)
,'remove'
from startDay s
join endDay e
on s.startDate = e.startDate
and s.endDate = e.endDate
union
select startDate
,endDate
,Datediff(hour, startDate, endDate)
,'between'
from dates
where @callLogStart < startDate
except
select startDate
,endDate
,Datediff(hour, startDate, endDate)
,'between'
from dates
where @callLogEnd < endDate
) x
order by
case mark
when 'start' then 0
when 'between' then 1
when 'end' then 2
when 'remove' then 3
end
希望能有所帮助这稍微简单一点。只有一个select语句。我把每一步分解成它自己的一列,这样你就可以看到它是如何工作的。不过,您只需要最后一列就可以计算出小时数。它依赖于区域设置,因为它使用DateName,但只要知道DATEFIRST设置为什么,您可以在一周中的某一天将其翻转过来 此外,这不包括假期。您必须创建自己的假日表。我引用了你可以链接到最终公式的地方 只需将开始和结束日期设置为您想要使用的任何日期,然后在代码中使用它,执行查找/替换,并用字段名替换这些参数。如果您使用的是SQL Server 2008或更高版本,则可以通过将打开/关闭时间转换为时间数据类型来简化很多操作。希望这有帮助
declare @startDate datetime = '2013-09-05 10:45:00.000',
@endDate datetime = '2013-09-06 08:15:00.000',
@zeroDate datetime = '1900-01-01 00:00:00.000',
@businessOpen datetime = '1900-01-01 08:00:00.000',
@businessClose datetime = '1900-01-01 17:00:00.000',
@hoursOpen int;
select @hoursOpen = datediff(hour, @businessOpen, @businessClose);
select @hoursOpen as hoursOpen
, @endDate - @startDate as actualTimeCallOpen
, datediff(week, @startDate, @endDate) as wholeWeekendsCallOpen
, datediff(day, @startDate, @endDate) as daysCallOpen
, (DATEDIFF(dd, @StartDate, @EndDate)) --get days apart
-(DATEDIFF(wk, @StartDate, @EndDate) * 2) --subtract whole weekends from the date (*2 is for 2 days per weekend)
+(CASE WHEN DATENAME(dw, @StartDate) = 'Sunday' THEN 1 ELSE 0 END) --subtract the start date if it started on sunday (thus, partial weekend)
-(CASE WHEN DATENAME(dw, @EndDate) = 'Saturday' THEN 1 ELSE 0 END) --subtract the end date if it ends on saturday (again, partial weekend)
as MthruFDaysOpen
, datediff(hour, @startDate, @endDate) as timeHoursCallOpen
, datediff(minute, @businessOpen, convert(datetime, '1900-01-01 ' + convert(varchar(8),@startDate,108))) / 60.0 as hoursOpenBeforeCall
, datediff(minute, convert(datetime, '1900-01-01 ' + convert(varchar(8), @endDate, 108)), @businessClose) / 60.0 as hoursOpenAfterCall
, (@hoursOpen - ((datediff(minute, convert(datetime, '1900-01-01 ' + convert(varchar(8), @endDate, 108)), @businessClose) + datediff(minute, @businessOpen, convert(datetime, '1900-01-01 ' + convert(varchar(8),@startDate,108)))) / 60.0)) as partialHourDay
, ( ((DATEDIFF(dd, @StartDate, @EndDate)) --get days apart,
- (DATEDIFF(wk, @StartDate, @EndDate) * 2) --subtract whole weekends from the date
+ (CASE WHEN DATENAME(dw, @StartDate) = 'Sunday' THEN 1 ELSE 0 END) --subtract the start date if it started on sunday (thus, partial weekend)
- (CASE WHEN DATENAME(dw, @EndDate) = 'Saturday' THEN 1 ELSE 0 END) --subtract the end date if it ends on saturday (again, partial weekend)
--If you have a table with holidays in it, you can subtract the count of holidays from this as well
--test where the holiday is between startdate and end date and the holiday itself isn't a saturday or sunday
) * @hoursOpen) --multiply the whole days open times hours per day, giving us
+ (@hoursOpen --start with hours open
- ( -- then subtract the sum of hours the business was open before and after the call
(datediff(minute, convert(datetime, '1900-01-01 ' + convert(varchar(8), @endDate, 108)), @businessClose) --calculate this different in minutes for greater accuracy
+ datediff(minute, @businessOpen, convert(datetime, '1900-01-01 ' + convert(varchar(8),@startDate,108)))
) / 60.0) --divide by 60 to convert back to hours before subtracting from @hours open
) as businessTimeOpen
谢谢你,约翰,我要吃一只鹅: