繁体   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