首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为两个日期之间的期间选择Sum HH:MM

为两个日期之间的期间选择Sum HH:MM
EN

Stack Overflow用户
提问于 2017-01-05 15:00:58
回答 1查看 181关注 0票数 2

我希望在2016年11月16日09:00 >2016年12月15日17:30之间工作小时(持续时间)之和。为了实现这一点,我需要计算两个日期之间的每一天的工作时间,然后将它们相加以获得每月工作时间。

EventTime表将包含用户每次上班时的时钟、午餐时间的时钟、午餐后的时钟以及一天结束时的时钟数据。

我已经成功地让它工作了一天:

代码语言:javascript
复制
EMPLOYEE    CLOCK IN            CLOCK OUT           DURATION
Tatjana     05/01/2017 08:33    05/01/2017 13:12    04:39
Harj        05/01/2017 10:59    05/01/2017 14:20    03:20
Tomasz      05/01/2017 09:55        
John        05/01/2017 09:57        
Sam         05/01/2017 08:11    05/01/2017 14:11    05:59
Paul        05/01/2017 09:39    05/01/2017 14:05    04:26
Adrian      05/01/2017 13:59        
Sophie      05/01/2017 08:42        
Meg         05/01/2017 07:56    05/01/2017 13:10    05:14
Anna        05/01/2017 07:59    05/01/2017 12:30    04:31
Adriana     05/01/2017 07:46    05/01/2017 12:44    04:58
Jacky       05/01/2017 09:01        
Anna        05/01/2017 07:57    05/01/2017 12:29    04:32
Kelly       05/01/2017 07:56    05/01/2017 12:45    04:48
Ana         05/01/2017 07:41    05/01/2017 14:13    06:32

以上是使用以下查询实现的:

代码语言:javascript
复制
SELECT
    u.Field14_50 AS EmployeeID,
    u.Firstname,
    u.Surname,
    MIN(e.EventTime) AS [Clocked In],
    CASE 
        WHEN MAX(e.EventTime) = MIN(e.EventTime) THEN NULL
        WHEN MAX(e.EventTime) > MIN(e.EventTime) THEN MAX(e.EventTime)
    END AS [Clocked Out],
    CASE
        WHEN MAX(e.EventTime) = MIN(e.EventTime) THEN NULL
        WHEN MAX(e.EventTime) > MIN(e.EventTime) THEN FORMAT((DATEDIFF(SECOND, MIN(e.EventTime), MAX(e.EventTime)) / 3600) % 24,  '00') + ':' + FORMAT((DATEDIFF(SECOND, MIN(e.EventTime), MAX(e.EventTime)) / 60) % 60, '00')
    END AS [Duration]
FROM
    UsersEx AS u
INNER JOIN
    EventsEx AS e
ON
    u.UserID = e.UserID
WHERE
    u.Field14_50 <> ''
AND
    u.DepartmentName IN (
        'Production',
        'Finance and Administration',
        'Purchase',
        'Sales',
        'Warehouse'
    )
AND
    DAY(e.EventTime) = DAY(GETDATE())     AND     MONTH(e.EventTime) = MONTH(GETDATE())      AND     YEAR(e.EventTime) = YEAR(GETDATE())
AND
    e.PeripheralName IN ('TIME AND ATTENDANCE OFFICE (In)', 'TIME AND ATTENDANCE OFFICE (Out)')
GROUP BY
    u.Field14_50,
    u.UserID,
    u.FirstName,
    u.Surname
ORDER BY
    u.Surname ASC

我希望这是明确的。

提前谢谢。

更新日期: 06/01/2017

我可以使用以下查询:

代码语言:javascript
复制
SELECT
    u.FirstName,
    e.EventTime
FROM
    UsersEx AS u    
INNER JOIN
    EventsEx AS e
ON
    u.UserID = e.UserID
WHERE
    u.Field14_50 <> ''
AND
    e.EventTime > '2016/11/16'     AND     e.EventTime < '2016/12/16'
AND
    e.PeripheralName IN ('TIME AND ATTENDANCE OFFICE (In)', 'TIME AND ATTENDANCE OFFICE (Out)')
AND
    u.DepartmentName IN ('Finance and Administration')
ORDER BY
    u.Field14_50,
    e.EventTime
ASC

为了得到这个结果:

代码语言:javascript
复制
Ram 16/11/2016 09:12
Ram 16/11/2016 12:59
Ram 16/11/2016 13:39
Ram 16/11/2016 17:47
Ram 17/11/2016 09:35
Ram 17/11/2016 12:45
Ram 17/11/2016 13:11
Ram 17/11/2016 17:43
Ram 21/11/2016 09:14
Ram 21/11/2016 12:24
Ram 21/11/2016 12:53
Ram 21/11/2016 17:36
Ram 22/11/2016 09:18
Ram 22/11/2016 13:32
Ram 22/11/2016 17:45
Ram 23/11/2016 09:10
Ram 23/11/2016 13:13
Ram 23/11/2016 13:51
Ram 24/11/2016 09:10
Ram 24/11/2016 13:15
Ram 24/11/2016 13:50
Ram 24/11/2016 17:41
Ram 25/11/2016 09:12
Ram 25/11/2016 17:36
Ram 28/11/2016 09:05
Ram 28/11/2016 12:32
Ram 28/11/2016 13:12
Ram 28/11/2016 17:40
Ram 29/11/2016 09:17
Ram 29/11/2016 12:45
Ram 29/11/2016 13:16
Ram 29/11/2016 17:50
Ram 30/11/2016 09:15
Ram 30/11/2016 12:51
Ram 30/11/2016 13:55
Ram 30/11/2016 17:31
Ram 01/12/2016 09:10
Ram 01/12/2016 12:44
Ram 01/12/2016 13:12
Ram 01/12/2016 17:36
Ram 02/12/2016 09:00
Ram 02/12/2016 12:19
Ram 02/12/2016 12:51
Ram 02/12/2016 17:38
Ram 05/12/2016 09:14
Ram 05/12/2016 12:45
Ram 05/12/2016 13:28
Ram 05/12/2016 17:45
Ram 06/12/2016 09:32
Ram 06/12/2016 12:15
Ram 06/12/2016 12:49
Ram 06/12/2016 17:51
Ram 07/12/2016 09:09
Ram 07/12/2016 12:43
Ram 07/12/2016 13:22
Ram 07/12/2016 17:51
Ram 08/12/2016 09:18
Ram 08/12/2016 12:54
Ram 08/12/2016 13:16
Ram 08/12/2016 17:39
Ram 09/12/2016 09:09
Ram 09/12/2016 18:02
Ram 12/12/2016 09:20
Ram 12/12/2016 12:55
Ram 12/12/2016 13:20
Ram 12/12/2016 17:47
Ram 13/12/2016 09:13
Ram 13/12/2016 13:10
Ram 13/12/2016 13:37
Ram 13/12/2016 18:01
Ram 15/12/2016 09:07
Ram 15/12/2016 12:37
Ram 15/12/2016 13:12
Ram 15/12/2016 17:53
Yuka    16/11/2016 08:52
Yuka    16/11/2016 19:05
Yuka    17/11/2016 09:02
Yuka    17/11/2016 18:25
Yuka    18/11/2016 08:23
Yuka    18/11/2016 18:26
Yuka    21/11/2016 08:12
Yuka    21/11/2016 17:59
Yuka    22/11/2016 08:51
Yuka    22/11/2016 17:44
Yuka    23/11/2016 08:43
Yuka    23/11/2016 18:07
Yuka    24/11/2016 08:42
Yuka    24/11/2016 18:24
Yuka    25/11/2016 08:37
Yuka    25/11/2016 17:34
Yuka    28/11/2016 08:44
Yuka    28/11/2016 18:03
Yuka    29/11/2016 08:11
Yuka    29/11/2016 16:58
Yuka    12/12/2016 08:51
Yuka    12/12/2016 17:57
Yuka    13/12/2016 07:51
Yuka    13/12/2016 18:30
Yuka    14/12/2016 08:32
Yuka    14/12/2016 18:04
Yuka    15/12/2016 08:40
Yuka    15/12/2016 18:09
Duncan  16/11/2016 07:25
Duncan  16/11/2016 18:28
Duncan  17/11/2016 07:25
Duncan  17/11/2016 17:48
Duncan  18/11/2016 07:29
Duncan  21/11/2016 07:33
Duncan  21/11/2016 17:48
Duncan  22/11/2016 07:31
Duncan  22/11/2016 18:14
Duncan  23/11/2016 07:43
Duncan  24/11/2016 07:21
Duncan  25/11/2016 07:32
Duncan  28/11/2016 07:35
Duncan  28/11/2016 18:11
Duncan  29/11/2016 07:34
Duncan  30/11/2016 07:35
Duncan  30/11/2016 18:21
Duncan  01/12/2016 07:27
Duncan  01/12/2016 17:57
Duncan  02/12/2016 07:38
Duncan  05/12/2016 07:29
Duncan  05/12/2016 18:12
Duncan  06/12/2016 07:28
Duncan  06/12/2016 17:37
Duncan  07/12/2016 07:13
Duncan  07/12/2016 07:19
Duncan  07/12/2016 18:01
Duncan  08/12/2016 07:22
Duncan  08/12/2016 17:56
Duncan  09/12/2016 07:24
Duncan  09/12/2016 17:30

现在,我如何从该结果集中获得每个用户每天的最小值和最大值(如下所示)?

代码语言:javascript
复制
Employee   Clocked In         Clocked Out        Duration
Ram        16/11/2016 09:12   16/11/2016 17:47   08:35
Ram        17/11/2016 09:35   17/11/2016 17:43   08:08
... 
Ram        13/12/2016 09:13   13/12/2016 18:01   08:48
Ram        15/12/2016 09:07   15/12/2016 17:53   08:46

and so on for each employee...
EN

回答 1

Stack Overflow用户

发布于 2017-01-05 15:14:29

将每个持续时间字段转换为,然后将其添加到HH:MM格式

这就是一个例子:

代码语言:javascript
复制
IF OBJECT_ID('tempdb..#tmp') IS NOT NULL
    DROP TABLE #tmp

CREATE TABLE #tmp (
    Id INT IDENTITY
    , duration VARCHAR(MAX)
    )

INSERT INTO #tmp (duration)
VALUES ('04:39')
    , ('03:20')
    , ('05:59')

SELECT 
    Sum(Left(duration, 2) * 3600 + substring(duration, 4, 2) * 60) AS seconds
    , CONVERT(VARCHAR, DATEADD(ms, (Sum(Left(duration, 2) * 3600 + substring(duration, 4, 2) * 60)) * 1000, 0), 114) AS 'seconds to HH:MM'
    --http://stackoverflow.com/questions/1262497/how-to-convert-seconds-to-hhmmss-using-t-sql
FROM #tmp

DROP TABLE #tmp

结果

代码语言:javascript
复制
seconds     seconds to HH:MM
----------- ------------------------------
50280       13:58:00:000

(1 row(s) affected)

在查询中实现此解决方案的一个选项是使用CTE。在这种情况下,带有CTE的情况如下所示:

代码语言:javascript
复制
;WITH Base
AS (
    SELECT u.Field14_50 AS EmployeeID
        , u.Firstname
        , u.Surname
        , MIN(e.EventTime) AS [Clocked In]
        , CASE 
            WHEN MAX(e.EventTime) = MIN(e.EventTime)
                THEN NULL
            WHEN MAX(e.EventTime) > MIN(e.EventTime)
                THEN MAX(e.EventTime)
            END AS [Clocked Out]
        , CASE 
            WHEN MAX(e.EventTime) = MIN(e.EventTime)
                THEN NULL
            WHEN MAX(e.EventTime) > MIN(e.EventTime)
                THEN FORMAT((DATEDIFF(SECOND, MIN(e.EventTime), MAX(e.EventTime)) / 3600) % 24, '00') + ':' + FORMAT((DATEDIFF(SECOND, MIN(e.EventTime), MAX(e.EventTime)) / 60) % 60, '00')
            END AS [Duration]
    FROM UsersEx AS u
        INNER JOIN EventsEx AS e
            ON u.UserID = e.UserID
    WHERE u.Field14_50 <> ''
        AND u.DepartmentName IN (
            'Production'
            , 'Finance and Administration'
            , 'Purchase'
            , 'Sales'
            , 'Warehouse'
            )
        AND DAY(e.EventTime) = DAY(GETDATE())
        AND MONTH(e.EventTime) = MONTH(GETDATE())
        AND YEAR(e.EventTime) = YEAR(GETDATE())
        AND e.PeripheralName IN (
            'TIME AND ATTENDANCE OFFICE (In)'
            , 'TIME AND ATTENDANCE OFFICE (Out)'
            )
    GROUP BY u.Field14_50
        , u.UserID
        , u.FirstName
        , u.Surname
    --ORDER BY u.Surname ASC --Don't include ORDER BY here.
    )
SELECT CONVERT(VARCHAR, DATEADD(ms, (Sum(Left(duration, 2) * 3600 + substring(duration, 4, 2) * 60)) * 1000, 0), 114) AS 'sum of hours (Duration)'
FROM Base
ORDER BY u.Surname

更新

根据您的更新,您需要使用MINMAX聚合函数进行查询,但需要由执行组以获取转换为DATE的日期。有了这个,你就可以得到每天的最高值和最低值。

代码:

代码语言:javascript
复制
SELECT u.FirstName
    , MIN(e.EventTime) AS 'Clocked In'
    , CASE 
        WHEN MIN(e.EventTime) = MAX(e.EventTime)
            THEN NULL
        ELSE MAX(e.EventTime)
        END AS 'Clocked Out'
    , DATEDIFF(SECOND, min(e.EventTime), MAX(e.EventTime)) AS 'Duration in seconds'
    , CONVERT(VARCHAR, DATEADD(ms, DATEDIFF(SECOND, min(e.EventTime), MAX(e.EventTime)) * 1000, 0), 114) AS 'Duration'
FROM UsersEx AS u
    INNER JOIN EventsEx AS e
        ON u.UserID = e.UserID
WHERE u.Field14_50 <> ''
    AND e.EventTime > '2016/11/16'
    AND e.EventTime < '2016/12/16'
    AND e.PeripheralName IN (
        'TIME AND ATTENDANCE OFFICE (In)'
        , 'TIME AND ATTENDANCE OFFICE (Out)'
        )
    AND u.DepartmentName IN ('Finance and Administration')
GROUP BY u.FirstName
    , cast(e.EventTime AS DATE)
ORDER BY u.FirstName

然后,只需将秒和起来,并使用CTE或Subquery将它们转换为我向您展示的HH:MM格式。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41488177

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档