Sql 每两行的DATEDIFF之和(以分钟为单位)
我正在尝试对第三方员工时间跟踪数据库运行查询。据我所知,他们并没有对员工全天的工作时间进行统计。我拥有的是一系列包含用户ID和时间戳的行。如果我按时间戳对行进行排序,我可以有效地获得它们的穿孔历史。如果我假设第一个冲头在,第二个冲头在,第三个冲头在,等等,是否有一种有效的方法从每隔一行找到DATEDIFF(以分钟为单位),然后将它们相加,得到该员工一天的总时间Sql 每两行的DATEDIFF之和(以分钟为单位),sql,sql-server,sql-server-2008,datediff,Sql,Sql Server,Sql Server 2008,Datediff,我正在尝试对第三方员工时间跟踪数据库运行查询。据我所知,他们并没有对员工全天的工作时间进行统计。我拥有的是一系列包含用户ID和时间戳的行。如果我按时间戳对行进行排序,我可以有效地获得它们的穿孔历史。如果我假设第一个冲头在,第二个冲头在,第三个冲头在,等等,是否有一种有效的方法从每隔一行找到DATEDIFF(以分钟为单位),然后将它们相加,得到该员工一天的总时间 badge_no punch_timestamp 11209 1/31/14 7:58 AM 11209
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分钟,我就看到了这篇帖子:
我先试试看 这里有一个相对简单、天真的方法。假设,如您所说,每个“奇数”行是一个戳入,每个“偶数”行是一个戳出,您可以分别获取奇数行和偶数行并计算每个工作块。请注意,我使用的
DateDiff
以分钟(mi
)为单位,但您可以将其更改为小时/秒/任意值:
以下是我使用的测试数据:
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]
最后总结每个徽章编号的时间:
SELECT [badge_no]
,SUM([Minutes])
FROM TimesPerBadge_No
GROUP BY [badge_no]
SELECT [badge_no]
,SUM([Minutes])
FROM TimesPerBadge_No
GROUP BY [badge_no]