[英]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.