Sql 让员工工作小时数
我有一个表,其中有一个名为Sql 让员工工作小时数,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我有一个表,其中有一个名为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 当实际结果为小时数=7.59时,我的查询结果为小时数=7.99 我要7.59分的结果 SELECT USERID , c
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
当实际结果为小时数=7.59时,我的查询结果为小时数=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)
用以下方式表达您的查询:
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
您提供了一个示例查询和示例数据。 但样本数据不完整。请为CHECKTYPE添加值,因为这将使我们更容易提供解决方案。 同时,它避免了彼得不得不做的任何不必要的工作/猜测。
最后,像“它不起作用”这样的回复等于没有回复,因为它不会让我们更进一步……首先,让我们做一些测试数据:(我随意添加了一个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来找到下一行,这样我们就可以得到时钟输入和时钟输出的开始和结束
;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
)
现在我们查询数据以查找基于时钟的工作分钟数(RN 1作为第一个时钟输入/时钟输出,RN 3作为第二个时钟输入/时钟输出,如果您允许更多,只需为每个组添加接下来的两个奇数)
以下是工作小时/分钟的输出:
EmpId DiffTime DiffHour DiffMinute
1 479 7 59
2 957 15 57
对不起,我理解起来有点困难。你是说你的结果是以十进制小时为单位的,你想把它转换成小时和分钟吗?不,结果是以小时为单位的,但不是小数部分。99需要转换成分钟……我想是这样的……你想添加你正在处理请求的表的结构吗nd提供一个示例?问题是它们不是两个代表签入和签出的列,只有一个名为CHECKTIME…对我的原始查询有帮助吗?
EmpId DiffTime DiffHour DiffMinute
1 479 7 59
2 957 15 57