簡體   English   中英

每兩行的DATEDIFF的總和,以分鍾為單位

[英]SUM of DATEDIFF in minutes for each 2 rows

我正在嘗試針對第三方員工時間跟蹤數據庫運行查詢。 據我所知,他們不會在一天的員工時間內保持總計。 我所擁有的是一系列包含用戶ID和時間戳的行。 如果我按時間戳排序行,我會有效地獲得他們的拳擊歷史。 如果我假設沖頭1在,沖頭2出來,沖頭3在等等,是否有一種有效的方法在幾分鍾內從每隔一行找到DATEDIFF,然后將它們相加以獲得當天的總時間那個員工?

    badge_no punch_timestamp
    11209   1/31/14 7:58 AM
    11209   1/31/14 9:57 AM
    11209   1/31/14 10:00 AM
    11209   1/31/14 10:07 AM

我發布后不到2分鍾,我遇到了這篇文章: SQL Server在不同的行之間找到datediff,sum

我先試試。

這是一種相對簡單,天真的方式。 假設,就像你說的那樣,每個“奇數”行都是一個標記,每個“偶數”行都是一個標記,你可以分別抓住奇數行和偶數行並計算每個工作塊。 請注意,我使用的DateDiff是以分鍾( mi )為單位,但您可以將其更改為小時/秒/無論如何: http//technet.microsoft.com/en-us/library/ms189794.aspx

;WITH StartTime AS
(
SELECT
    badge_no,
    punch_timestamp,
    myrow
FROM
(
    SELECT
        badge_no,
        punch_timestamp,
        ROW_NUMBER() OVER (Partition BY badge_no ORDER BY punch_timestamp ASC) as myrow
    FROM #Time
) [t1]
WHERE myrow % 2 = 1 --odd rows
)
,EndTime AS
(
SELECT
    badge_no,
    punch_timestamp,
    myrow - 1 as 'myrow' --Subtract 1 to match up with the odd rows
FROM
(
    SELECT
        badge_no,
        punch_timestamp,
        ROW_NUMBER() OVER (Partition BY badge_no ORDER BY punch_timestamp ASC) as myrow
    FROM #Time
) [t1]
WHERE myrow % 2 = 0 --even rows
)

SELECT
    badge_no,
    SUM(diff) as 'MinutesWorked'
FROM 
(
SELECT
    EndTime.badge_no,
    DATEDIFF(mi, 
             (SELECT TOP 1 
                  punch_timestamp 
              FROM StartTime 
              WHERE StartTime.badge_no = EndTime.badge_no 
                  AND StartTime.myrow = EndTime.myrow), 
             EndTime.punch_timestamp) as 'diff'
FROM EndTime
) [t1]
GROUP BY badge_no

這是我使用的測試數據:

CREATE TABLE #Time
(
    badge_no nvarchar(10),
    punch_timestamp datetime
)

INSERT INTO #Time VALUES ('100', '2013-01-02 12:01 PM')
INSERT INTO #Time VALUES ('100', '2013-01-02 1:38 PM')
INSERT INTO #Time VALUES ('100', '2013-01-02 2:29 PM')
INSERT INTO #Time VALUES ('100', '2013-01-03 3:01 PM')
INSERT INTO #Time VALUES ('100', '2013-01-03 4:20 PM')
INSERT INTO #Time VALUES ('100', '2013-01-04 12:01 PM')
INSERT INTO #Time VALUES ('100', '2013-01-04 2:01 PM')
INSERT INTO #Time VALUES ('100', '2013-01-04 3:11 PM')
INSERT INTO #Time VALUES ('100', '2013-01-04 4:21 PM')
INSERT INTO #Time VALUES ('100', '2013-01-05 12:01 PM')
INSERT INTO #Time VALUES ('100', '2013-01-05 1:01 PM')
INSERT INTO #Time VALUES ('200', '2013-01-04 2:11 AM')
INSERT INTO #Time VALUES ('200', '2013-01-04 4:34 PM')
INSERT INTO #Time VALUES ('200', '2013-01-05 1:01 AM')
INSERT INTO #Time VALUES ('200', '2013-01-05 4:29 AM')

使用@DaveZych樣本數據,我設法使用下面的SQL語句計算與他相同的結果:

;WITH DataSource ([StartOrEnd], [badge_no], [punch_timestamp]) AS
(
    SELECT ROW_NUMBER() OVER (PARTITION BY [badge_no] ORDER BY [punch_timestamp]) +
           ROW_NUMBER() OVER (PARTITION BY [badge_no] ORDER BY [punch_timestamp])  % 2
          ,[badge_no]
          ,[punch_timestamp]
    FROM #Time
),
TimesPerBadge_No ([badge_no], [StartOrEnd], [Minutes]) AS
(
    SELECT  [badge_no]
           ,[StartOrEnd] 
           ,DATEDIFF(MINUTE, MIN([punch_timestamp]), MAX([punch_timestamp]))
    FROM DataSource
    GROUP BY [badge_no]
            ,[StartOrEnd] 
)
SELECT [badge_no]
      ,SUM([Minutes])
FROM TimesPerBadge_No
GROUP BY [badge_no]

這里可以看到每個CTE的值:

首先,我們需要對每個開始和結束日期進行分組:

 SELECT ROW_NUMBER() OVER (PARTITION BY [badge_no] ORDER BY [punch_timestamp]) +
           ROW_NUMBER() OVER (PARTITION BY [badge_no] ORDER BY [punch_timestamp])  % 2
          ,[badge_no]
          ,[punch_timestamp]
    FROM #Time

在此輸入圖像描述

現在,我們可以計算每組的分鍾差異:

SELECT  [badge_no]
        ,[StartOrEnd] 
        ,DATEDIFF(MINUTE, MIN([punch_timestamp]), MAX([punch_timestamp]))
FROM DataSource
GROUP BY [badge_no]
        ,[StartOrEnd] 

在此輸入圖像描述

並最終sumarize每個badge_no的分鍾:

SELECT [badge_no]
      ,SUM([Minutes])
FROM TimesPerBadge_No
GROUP BY [badge_no]

在此輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM