我有这张表,其中包含员工的出勤情况。我想计算员工每个月花费的总时间。我能够计算每天花费的时间,但并不能增加时间并提供一个整体。
以下是指向shema的链接:https://liveweave.com/q0iBdb
这是计算每个员工每天花费时间的查询。
SELECT
CONVERT(VARCHAR(6), Datediff(second, CAST(MIN([AttendanceTimeIn]) AS TIME), CAST(MAX([AttendanceTimeOut]) AS TIME))/3600)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), (Datediff(second, CAST(MIN([AttendanceTimeIn]) AS TIME), CAST(MAX([AttendanceTimeOut]) AS TIME)) % 3600) / 60), 2)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), Datediff(second, CAST(MIN([AttendanceTimeIn]) AS TIME), CAST(MAX([AttendanceTimeOut]) AS TIME)) % 60) , 2 )
AS HoursSpent
FROM
[HRM].[tbl_EmployeeAttendance] [Attendance]
WHERE
[Attendance].[RecordStatusCode] != '13' AND [Attendance].[EmpCode] = 22
AND
CAST(GETDATE()-5 AS DATE) = CAST(ISNULL([AttendanceTimeIn], [AttendanceTimeOut]) AS Date)
这是我到目前为止尝试过的
SELECT CONVERT(varchar(10), SUM(DATEDIFF(MINUTE, CAST(AttendanceTimeIn AS TIME), CAST(AttendanceTimeOut AS TIME))) / 60) + ':' + CONVERT(varchar(10), SUM(DATEDIFF(MINUTE, CAST(AttendanceTimeIn AS TIME), CAST(AttendanceTimeOut AS TIME))) % 60)
FROM [HRM].[tbl_EmployeeAttendance]
WHERE CAST(COALESCE(AttendanceTimeIn, AttendanceTimeOut) AS DATE) BETWEEN '2018-08-01' AND GETDATE()
AND
RecordStatusCode != '13' AND EmpCode = 22
这些日期的预期输出约为55小时25分钟,但可能更多或更少。
答案 0 :(得分:0)
时间差的计算可以分为总小时数和剩余的分钟和秒数。
示例片段:
-- Using a table variable for demonstration purposes
declare @EmployeeAttendance table (ID int identity(1,1) primary key, EmpCode int, AttendanceTimeIn datetime, AttendanceTimeOut datetime);
-- Simplified sample data
insert into @EmployeeAttendance (EmpCode, AttendanceTimeIn, AttendanceTimeOut) values
(11,'2018-08-01 09:20:00', null)
,(11,null, '2018-08-01 21:35:15')
,(12,'2018-08-01 09:00:00', null)
,(12,null, '2018-08-01 22:20:20')
,(13,'2018-08-01 09:00:00',null)
,(13,'2018-08-01 12:00:00',null)
;
-- The query
WITH EMPLOYEEATTENDANCE AS
(
select
EmpCode,
cast(coalesce(AttendanceTimeIn, AttendanceTimeOut) as date) as AttendanceDate,
cast(min(AttendanceTimeIn) as time) as MinEmpTimeIn,
cast(max(AttendanceTimeIn) as time) as MaxEmpTimeIn,
cast(max(AttendanceTimeOut) as time) as MaxEmpTimeOut
--,max(cast(max(AttendanceTimeOut) as time)) over (partition by cast(coalesce(AttendanceTimeIn, AttendanceTimeOut) as date)) as MaxDateTimeOut
from @EmployeeAttendance
where cast(coalesce(AttendanceTimeIn, AttendanceTimeOut) as date) between cast('2018-08-01' as date) and cast('2018-08-01' as date)
group by EmpCode, cast(coalesce(AttendanceTimeIn, AttendanceTimeOut) as date)
)
SELECT
CONCAT(SUM(DATEDIFF(HOUR,MinEmpTimeIn, coalesce(MaxEmpTimeOut,MaxEmpTimeIn))),
SUBSTRING(CONVERT(varchar(30),
DATEADD(ms,(SUM(DATEDIFF(SECOND,MinEmpTimeIn, coalesce(MaxEmpTimeOut,MaxEmpTimeIn)))%3600)*1000,0)
,114),3,6)) as TotalTimeDiff
FROM EMPLOYEEATTENDANCE;
结果:
TotalTimeDiff
-------------
28:35:35
但是在示例数据中,只有1个EmpCode的AttendanceTimeOut。
而且与所有AttendanceTimeIn相比,它甚至太低了。
对于不完整的数据,可以预期会有不完整的结果。