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