2014-08-27 95 views
0

我有一個基於時間戳的數據集,即startdate,enddate。我想計算時間戳之間的工作小時數,例如典型的(M-F,8-5)周。在時間戳之間求和

例如,如果一張票在星期一上午8:00進入,並且週二上午9:00關閉,我希望該陳述顯示10個小時。我還需要在計算中省略週末。任何人都可以推薦一種解決方法嗎?感謝您的協助。

+0

我建議從前者減去後者的日期並轉換成小時/分鐘,然後用CASE邏輯處理非工作時間。 – 2014-08-27 20:08:57

回答

0

作爲一個例子(沒有你的表格結構在我面前),這是基於我爲generating rows for time做的另一個答案。

declare @datetimes table (id int primary key identity(1,1), startdatetime datetime, enddatetime datetime) 
insert into @datetimes (startdatetime,enddatetime) values 
     ('2014-08-26 08:00:00','2014-08-27 09:00:00') 
    , ('2014-07-16 08:00:00','2014-07-28 09:00:00') 

declare @defaultDayStart time = '08:00:00', @defaultDayEnd time = '17:00:00' 

select T.ID, sum(Z.ShadowHours) 
from (
     select id, startdatetime, enddatetime, datediff(hh,startdatetime,enddatetime) TotalTime 
     from @datetimes 
    ) T 
    CROSS APPLY (
      SELECT 
       RowID-1 AS ShadowDays 
       , CASE 
        WHEN DATENAME(dw,DATEADD(dd, RowID - 1,t.startdatetime)) IN ('Saturday', 'Sunday') THEN 0 
        ELSE DATEDIFF(hh, CASE RowID WHEN MIN(RowID)OVER(PARTITION BY t.id) THEN t.startdatetime ELSE CONVERT(DATETIME,CONVERT(DATE, DATEADD(dd, RowID - 1,t.startdatetime))) + @defaultDayStart END 
          , CASE RowID WHEN MAX(RowID)OVER(PARTITION BY t.id) THEN t.enddatetime ELSE CONVERT(DATETIME,CONVERT(DATE, DATEADD(dd, RowID - 1,t.startdatetime))) + @defaultDayEnd END 
          ) 
       END AS ShadowHours 
       , DATENAME(dw,DATEADD(dd, RowID - 1,t.startdatetime)) wd 
      FROM (
       SELECT ROW_NUMBER()OVER(ORDER BY S.NAME) AS RowID 
       FROM master..spt_values S 
       ) X 
      WHERE DATEDIFF(dd,startdatetime,enddatetime) + 1 >= RowID 
     ) Z 
GROUP BY T.id 

這個例子是基本的,並沒有使用包含假期的日曆表。這也沒有計算午餐時間,這應該在那裏,因爲大多數地方認爲這是非法的,不要在8小時的工作日內給予某種形式的用餐時間。這些是您可能會被要求適應的考慮因素。編輯您的問題,如果您想在此領域獲得幫助,請留下評論。