2016-07-10 11 views
0

我在TIME數據類型列中有一個包含員工登錄持續時間詳細信息的表XYZ。在SQL服務器上使用T-SQL獲取正在運行的總時間列

EmployeeID | DomainID | LoginDuration 
---------------------------------------------------------------- 
     1111   12  02:32:55:0000000 
     1111   4  00:57:17.0000000 
     1111   12  01:06:25.0000000 
     1111   11  03:31:23.0000000 
     2222   11  02:42:17.0000000 
     2222   4  03:54:52.0000000 
     2222   10  04:08:29.0000000 

除了以上的專欄中,我也有LoginTimeStampLoginWeek列,我使用的JOIN語句其中。

我試圖獲得用於LoginDuration柱運行總計如下:

EmployeeID | DomainID | HoursBefore  | LoginDuration  | HoursAfter | 
--------------------------------------------------------------------------------- 
     1111   12  00:00:00.0000000 02:32:55:0000000 **00:00:00.0000000** 
     1111   4  02:32:55.0000000 00:57:17.0000000 03:30:12.0000000 
     1111   12  03:30:12.0000000 01:06:25.0000000 04:36:37.0000000 
     1111   11  04:36:37.0000000 03:31:23.0000000 08:08:00.0000000 
     2222   11  00:00:00.0000000 02:42:17.0000000 **00:00:00.0000000** 
     2222   4  01:32:31.0000000 03:54:52.0000000 04:14:48.0000000 
     2222   10  04:14:48.0000000 04:08:29.0000000 08:09:40.0000000 

HoursBefore是HoursAfter的先前值(00:00:00爲每個員工的第一行)

HoursAfter = HoursBefore + LoginDuration

爲此,我寫了下面的查詢,但我在HoursAfter列出現錯誤。它不會爲每個員工增加當前值和以前的值。

SELECT 
    a.EmployeeID,a.LoginDuration, 
    COALESCE(CAST(
     DATEADD(ms, 
      SUM(DATEDIFF(ms,0,CAST(b.LoginDuration as datetime))) 
      , 0) 
     as time) 
     ,'00:00:00') AS HoursBefore, 
    a.LoginDuration as Hours, 
    COALESCE(CAST(
     DATEADD(ms, 
      SUM(DATEDIFF(ms,0,CAST(b.LoginDuration as datetime))) 
      , a.Loginduration) 
     as time) 
     ,'00:00:00') As HoursAfter 
FROM XYZ AS a 
LEFT OUTER JOIN XYZ AS b 
ON (a.EmployeeID = b.EmployeeID) 
    AND (a.LoginWeek = b.LoginWeek) 
    AND (b.LoginTimeStamp < a.LoginTimeStamp) 
GROUP BY a.EmployeeID, a.LoginTimeStamp,a.LoginDuration 
ORDER BY a.LoginWeek, a.EmployeeID, a.LoginTimeStamp; 

我需要幫助與查詢,從而爲每個員工HoursAfter列爲宜。

任何幫助將不勝感激。 (這是我的第一個查詢,如果您需要更多詳細信息,請回復。)

謝謝。

+1

什麼時間前幾小時和幾小時後? – sagi

+0

粘貼DDL,DML查詢非常簡單。查看此Addin:https://github.com/nycdotnet/TSqlFlex .. – TheGameiswar

+0

Hello Ivan, HoursBefore是HoursAfter的以前值(00:00:00爲第一行每個員工) HoursAfter = HoursBefore + LoginDuration –

回答

-1

使用OUTER APPLY來計算小時後。小時之前只是時間減去當前時間

SELECT a.EmployeeID, a.DomainID, 
     HoursBefore = CONVERT(TIME, DATEADD(SECOND, b.after_secs - DATEDIFF(SECOND, 0, a.LoginDuration), 0)), 
     a.LoginDuration, 
     HoursAfter = CONVERT(TIME, DATEADD(SECOND, b.after_secs, 0)) 
FROM XYZ AS a 
OUTER APPLY 
(
     SELECT after_secs = SUM(DATEDIFF(SECOND, 0, x.LoginDuration)) 
     FROM XYZ x 
     WHERE x.EmployeeID   = a.EmployeeID 
     AND  x.LoginWeek   = a.LoginWeek 
     AND  x.LoginTimeStamp <= a.LoginTimeStamp 
) b 
0

可惜SQL Server不支持的數據類型期間還後,它將使數學這麼簡單得多。

然而,DOS對窗口功能相當不錯的支持,在新版本中,我們可以用它來解決這個問題:

declare @t table (ID int, EmployeeID int, DomainID int, LoginDuration time) 

insert @t 
values 
(1, 1111,   12,  '02:32:55.0000000'), 
(2, 1111,   4,  '00:57:17.0000000'), 
(3, 1111,   12,  '01:06:25.0000000'), 
(4, 1111,   11,  '03:31:23.0000000'), 
(5, 2222,   11,  '02:42:17.0000000'), 
(6, 2222,   4,  '03:54:52.0000000'), 
(7, 2222,   10,  '04:08:29.0000000') 

;with x as (
    select *, dateadd(second, sum(datediff(second, 0, loginduration)) over (partition by employeeid order by id), 0) sum_duration_sec, 
     row_number() over (partition by employeeid order by id) rn 
    from @t 
) 
select 
    employeeid, 
    domainid, 
    convert(time, isnull(lag(sum_duration_sec) over (partition by employeeid order by id),0)) hoursbefore, 
    loginduration, 
    convert(time, case when rn = 1 then 0 else sum_duration_sec end) hoursafter 
from x 

我介紹了簡潔的ID列建立的順序,你可能想要使用(LoginWeek,LoginTimestamp)來排序。

另外,不清楚第1行和第5行的HoursAfter應該爲0的要求 - 如果沒有,請刪除row_number()。

相關問題