简体   繁体   English

获取员工工作时间

[英]Get Employee Hours Worked

I have a table with a DATETIME column named CHECKTIME that represents when the employee clocked in/out. 我有一个表,其中有一个名为CHECKTIME的DATETIME列,该列表示员工何时CHECKTIME / CHECKTIME Basically, I have a query that does that function but the conversion is not correct. 基本上,我有一个执行该功能的查询,但转换不正确。 Example below. 下面的例子。

CHECKTIME

2014-04-28 07:58:36.000
2014-04-28 12:00:27.000
2014-04-28 13:00:02.000
2014-04-28 16:57:45.000

My query result gives me Hour = 7.99 when the real result is Hours = 7.59. 当实际结果为Hours = 7.59时,我的查询结果为我提供Hour = 7.99。

I want the 7.59 result. 我想要7.59的结果。

SELECT  USERID
       , convert(varchar(10),CHECKTIME,101) as Date
       , SUM(CASE WHEN CHECKTYPE='I' 
                      THEN -1*(datepart(hh,[CHECKTIME])+datepart(mi,[CHECKTIME])/60.0)
                      ELSE datepart(hh,[CHECKTIME])+datepart(mi,[CHECKTIME])/60.0  END) AS Hours

FROM [CHECKINOUT]
WHERE USERID=1003
GROUP BY USERID, CONVERT(varchar(10),[CHECKTIME],101)

Expressing your query like this: 像这样表达您的查询:

with data(InTime,OutTIme) as (
    select InTime,OutTIme from (values
         (convert(datetime,'2014-04-28 07:58:36.000',120), convert(datetime,'2014-04-28 12:00:27.000',120))
        ,(convert(datetime,'2014-04-28 13:00:02.000',120), convert(datetime,'2014-04-28 16:57:45.000',120))
    )data(InTime,OutTIme)
)
select  cast(dateadd(n,sum(datediff(n,intime,outtime)),0) as time)
from data
go

yields this: 产生这个:

07:59:00.0000000

where I have taken the liberty of pre-pivoting the data manually in order to focus attention on how to construct the time conversion formula. 在这里,我采取了手动将数据预先透视的自由方式,以便将注意力集中在如何构造时间转换公式上。

Update : - amended to include the pivot, generating the same value: 更新 :-修改为包括枢轴,生成相同的值:

with data(CheckTime) as (
    select CheckTime from (values
         (convert(datetime,'2014-04-28 07:58:36.000',120))
        ,(convert(datetime,'2014-04-28 12:00:27.000',120))
        ,(convert(datetime,'2014-04-28 13:00:02.000',120))
        ,(convert(datetime,'2014-04-28 16:57:45.000',120))
    )data(CheckTime)
),
pvt as (
    select
        CheckInOut
       ,[0]   as OutTime
       ,[1]   as InTime  
    from (
        select 
             CheckTime
            ,(ROW_NUMBER() over(order by CheckTime)-1) / 2 as CheckInOut
            ,(ROW_NUMBER() over(order by CheckTime)) % 2 as rn
        from data
    )t
    pivot (max(CheckTime) for rn in ([1], [0])) pvt

)
select  cast(dateadd(n,sum(datediff(n,intime,outtime)),0) as time)
from pvt
go

You provided a sample query and sample data. 您提供了示例查询和示例数据。 But the sample data are incomplete. 但是样本数据不完整。 Please add the values for CHECKTYPE since this will make it a lot easier for us to provide a solution. 请添加CHECKTYPE的值,因为这将使我们更轻松地提供解决方案。 At the same time it avoids any unnecessary work/guessing like Peter had to do. 同时,它避免了像Peter所做的任何不必要的工作/猜测。 Finally, a reply like "it doesn't work" is equal to no reply since it doesn't bring us a single step further.... 最后,像“它不起作用”之类的答复等于没有答复,因为它没有使我们更进一步。

First, lets make some test data: (I took the liberty of adding a emp id column so I could add multiple employee times. 首先,让我们做一些测试数据:(我随意添加了一个emp id列,这样我就可以添加多个员工时间。

DECLARE @CheckDate TABLE
(
    EmpId INT,
    CheckTime DATETIME
)

INSERT INTO @CheckDate
( EmpId, CheckTime ) 
VALUES
(1, '2014-04-28 07:58:36.000'),
(1, '2014-04-28 12:00:27.000'),
(1, '2014-04-28 13:00:02.000'),
(1, '2014-04-28 16:57:45.000'),
(2, '2014-04-27 1:00:02.000'),
(2, '2014-04-27 16:57:45.000');

Now we make a CTE to find the next row so we can get a begin and end of the clockin and clockout. 现在,我们进行CTE查找下一行,以便获得时钟输入和时钟输出的开始和结束。

;WITH CheckRows AS
(
    SELECT *,
        ROW_NUMBER() OVER (PARTITION BY EmpId ORDER BY CheckTime) RN
    FROM @CheckDate p
),
CheckBreaks AS
(
    SELECT 
        p.EmpId, 
        p.CheckTime, 
        p.RN, 
        ISNULL(n.CheckTime, 0) NextTime
    FROM CheckRows p
    INNER JOIN CheckRows n
        ON n.RN = p.RN + 1
        AND n.EmpId = p.EmpId
)

Now we query the data to find the minutes worked based on the clockins (RN 1 as first clockin/clockout, RN 3 as second clockin/clockout, if you allow for more, just add the next couple of odd numbers for each group) 现在,我们查询数据以找到基于时钟的分钟数(RN 1为第一时钟/时钟输出,RN 3为第二时钟/时钟输出,如果允许更多,只需为每组添加下几个奇数)

SELECT 
    c.EmpId,
    SUM(CASE WHEN c.RN = 1 OR c.RN = 3 THEN DATEDIFF(MINUTE, c.CheckTime, c.NextTime) ELSE 0 END) DiffTime,
    SUM(CASE WHEN c.RN = 1 OR c.RN = 3 THEN DATEDIFF(MINUTE, c.CheckTime, c.NextTime) ELSE 0 END) / 60 DiffHour,
    SUM(CASE WHEN c.RN = 1 OR c.RN = 3 THEN DATEDIFF(MINUTE, c.CheckTime, c.NextTime) ELSE 0 END) % 60 DiffMinute
FROM CheckBreaks c
GROUP BY c.EmpId

Here is the output for the hour / minutes worked: 这是工作小时/分钟的输出:

EmpId   DiffTime    DiffHour    DiffMinute
1   479 7   59
2   957 15  57

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM