我有一个名为CHECKTIME
的DATETIME列表,表示员工进/出时间。基本上,我有一个查询来执行该功能,但转换不正确。示例如下。
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
当实际结果为Hours = 7.59时,我的查询结果给出了Hour = 7.99。
我想要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)
答案 0 :(得分:0)
表达您的查询:
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
得出这个:
07:59:00.0000000
我可以自由地手动预先转动数据,以便集中注意如何构建时间转换公式。
更新: - 修改为包含枢轴,生成相同的值:
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
答案 1 :(得分:0)
您提供了示例查询和示例数据。 但样本数据不完整。请添加CHECKTYPE的值,因为这样可以使我们更容易提供解决方案。 同时,它避免了彼得必须做的任何不必要的工作/猜测。 最后,回复就像"它没有工作"等于没有回复,因为它没有给我们带来更进一步的步骤....
答案 2 :(得分:0)
首先,让我们制作一些测试数据:(我冒昧地添加了一个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');
现在我们做一个CTE来找到下一行,这样我们就可以获得clockin和clockout的开始和结束。
;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
)
现在我们查询数据以查找基于clockins工作的分钟数(RN 1作为第一个clockin / clockout,RN 3作为第二个clockin / clockout,如果你允许更多,只需为每个添加下一对奇数基)
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
以下是工作小时/分钟的输出:
EmpId DiffTime DiffHour DiffMinute
1 479 7 59
2 957 15 57