2016-12-07 3 views
0

Я ищу сценарий T-Sql для вычисления общего количества часов между двумя датами, но только если он попадает в определенный период.Общее количество часов между датами с использованием T-SQL

У меня есть таблица под названием Жалобы с различными столбцами, включая ContactDate и ResolvedDate.

Я хочу рассчитать общее время в часах, если оно попадает в часы работы. 9-5pm Пн-Пт и 12-4pm Сб и Солнца.

Так, например, если бы я получил жалобу на 5 декабря в 3 часа и Решенный его на 6 декабря в 1pm, общее количество часов будет 3.

Другой пример я получил жалобу на 3 декабря и 12 вечера и разрешили его 6 декабря в 17:00, общее количество часов составит 24 часа.

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

+2

Что вы исследовали, примерил свой, и не нашел, что он не работает? Пока эта статья не показывает никаких усилий с вашей стороны. – dfundako

+1

Можете ли вы опубликовать то, что вы на самом деле пытались сделать? Если у вас есть что-то в этом роде, мы можем попытаться помочь вам? :) –

+0

Где твоя попытка? Мы можем помочь вам исправить ваш запрос, но мы не создаем запрос для вас. Вы даже проводите исследование? В Интернете много примеров. – Eric

ответ

0

Правильно, я не делаю все это для вас, но это даст вам возможность. Я бы создал таблицу с строкой данных за каждый час. В этом случае у меня будет флаг, показывающий, является ли это рабочим часом или нет, что-то вроде этого;

CREATE TABLE #DateTable (Time_Stamp datetime, Working_Hour int) 
INSERT INTO #DateTable (Time_Stamp, Working_Hour) 
VALUES 
('2016-12-05 14:00:00',1) 
,('2016-12-05 15:00:00',1) 
,('2016-12-05 16:00:00',1) 
,('2016-12-05 17:00:00',0) 
,('2016-12-05 18:00:00',0) 
,('2016-12-05 19:00:00',0) 
,('2016-12-05 20:00:00',0) 
,('2016-12-05 21:00:00',0) 
,('2016-12-05 22:00:00',0) 
,('2016-12-05 23:00:00',0) 
,('2016-12-05 00:00:00',0) 
,('2016-12-06 01:00:00',0) 
,('2016-12-06 02:00:00',0) 
,('2016-12-06 03:00:00',0) 
,('2016-12-06 04:00:00',0) 
,('2016-12-06 05:00:00',0) 
,('2016-12-06 06:00:00',0) 
,('2016-12-06 07:00:00',0) 
,('2016-12-06 08:00:00',0) 
,('2016-12-06 09:00:00',0) 
,('2016-12-06 10:00:00',0) 
,('2016-12-06 11:00:00',0) 
,('2016-12-06 12:00:00',1) 
,('2016-12-06 13:00:00',1) 
,('2016-12-06 14:00:00',1) 
,('2016-12-06 15:00:00',1) 

Образец списка вызовов;

CREATE TABLE #Calls (Call_ID int, StartDate datetime, EndDate datetime) 
INSERT INTO #Calls (Call_ID, StartDate, EndDate) 
VALUES 
(1,'2016-12-05 14:00:00','2016-12-06 14:00:00') 
,(2,'2016-12-05 15:00:00','2016-12-06 14:00:00') 
,(3,'2016-12-05 16:00:00','2016-12-06 14:00:00') 

Таким образом, вы можете присоединиться к этому, используя две даты и суммировать количество рабочих часов между ними, например:

SELECT 
    c.Call_ID 
    ,SUM(dt.Working_Hour) Working_Hour 
FROM #Calls c 
JOIN #DateTable dt 
    ON dt.Time_Stamp BETWEEN c.StartDate AND c.EndDate 
GROUP BY c.Call_ID 

Результат;

Call_ID Working_Hour 
1  6 
2  5 
3  4 

Если вы указали таблицу даты в Google, существует множество примеров, которые помогут вам заполнить таблицу дат.

+0

Я смотрел онлайн большую часть дня без везения. – FastEddie

+0

Спасибо за то, что посмотрели на этого Богатого, но я не хочу, чтобы один результат был заполнен жесткими закодированными датами. Мне нужен результат, чтобы заполнить каждую строку моего отчета. – FastEddie

+0

Почему так много враждебности? Разве это не источник помощи или информации? – FastEddie

0

Из памяти, когда я сделал это раньше ... (это не красиво)

with CTE as 
(
select CaseID, cast(ComplaintDate as date) as ComplaintDate, cast(CompaintDate as time) as CompTime, cast(ResolvedDate as date) as ResolvedDate, cast(ResolvedDate as time) as ResolvedTime, 
case 
    when datepart(dw,ResolvedDate) in (1,7) then cast('12:00:00' as TIME) 
    else cast('09:00:00' as time) 
end as ResStart, 
case 
    when datepart(dw,CompaintDate) in (1,7) then cast('16:00:00') as time 
    else cast('17:00:00' as time) 
end as ComEnd 
from Compaints 
) 
select CaseID, 
case 
when datepart(dd, ResolvedDate) > datepart(dd,ComplaintDate) then 
    datediff(hh, ResolvedTime, ResStart) + datediff(hh,ComEnd,ComplaintTime) + 8*datediff(dd,ResolvedDate,ComplaintDate) 
else DateDiff(hh,ResolvedTime,ComplaintTime) 
end as HoursOpen 
from CTE 
0

Рассмотрим следующее.

Мы фактически выполняем вычисления за считанные минуты, поэтому вы решаете округлить вверх/вниз, но результат возвращается в часах.

Следует отметить, что код в CROSS APPLY легко переносится в UDF.

Declare @YourTable table (ID int,OpenDT datetime, CloseDT datetime) 
Insert Into @YourTable values 
(1,'2016-12-02 16:00','2016-12-05 10:00'), 
(2,'2016-12-02 16:00','2016-12-05 09:45'), 
(3,'2016-12-07 09:00','2016-12-08 11:15') 

Select A.* 
     ,B.BusinessHours 
From @YourTable A 
Cross Apply (
       Select BusinessHours=count(*)/60.0 
       From (Select Top (DateDiff(MI,A.OpenDT,A.CloseDT)+5000) D=DateAdd(MI,Row_Number() over (Order By (Select NULL))-1,cast(cast(A.OpenDT as date) as datetime)) From master..spt_values N1,master..spt_values N2) D 
       Where D > A.OpenDT and D<= A.CloseDT 
        and (
         (DatePart(DW,D) between 2 and 6 and cast(D as time) between '09:01' and '17:00') 
         or 
         (DatePart(DW,D) = 7 and cast(D as time) between '12:01' and '16:00') 
         ) 
     ) B 

Возвращает

enter image description here

В качестве дополнительного бонуса, вы можете исключить праздники и (должен быть фактический таблицу)

and Cast(D as Date) Not In (Select Date From (Values 
             ('2016-01-01','New Year''s Day'), 
             ('2016-01-18','Martin Luther King, Jr,'), 
             ('2016-02-15','Washington''s Birthday'), 
             ('2016-03-25','Good Friday'), 
             ('2016-05-30','Memorial Day'), 
             ('2016-07-04','Independence Day'), 
             ('2016-09-05','Labor Day'), 
             ('2016-11-24','Thanksgiving'), 
             ('2016-11-25','Black Friday'), 
             ('2016-12-26','Christmas Day') 
           ) as H (Date,Name))