Reputation: 47
I have a Timeclock
table that has columns [employeeid]
, [clock in]
, and [clock out]
.
I need to figure out how many minutes they've worked for each HOUR, for example:
Clockin: 11:30
Clockout: 12:37
I need to know you have:
11 hour: 30 min
12 hour: 37 min
Table structure:
|empid(int)|clockin(time(7))|clockout(time(7))|
| 103| 11:37:00| 12:37:00|
Here's my failed attempt:
select
hourlist.hour, employeelabor.empposid,
case
when employeelabor.clockin < hourlist.hour
and employeelabor.clockout >= dateadd(HH,1,hourlist.hour)
then '1:00:00.0'
when employeelabor.clockin >= hourlist.hour
and employeelabor.clockout < dateadd(HH,1,hourlist.hour)
then datediff(mi, employeelabor.clockout, employeelabor.clockin)
when employeelabor.clockin >= hourlist.hour
and employeelabor.clockout > dateadd(HH,1,hourlist.hour)
then datediff(mi, 1, dateadd(mi, hourlist.hour, 1))
when employeelabor.clockin < hourlist.hour
and employeelabor.clockout < dateadd(HH,1,hourlist.hour)
then datediff(mi, hourlist.hour, employeelabor.clockout)
else 0
end minworked
from
hourlist
JOIN
dbo.EmployeeLabor ON (employeelabor.clockin >= hourlist.hour
and employeelabor.clockin < dateadd(HH, 1, hourlist.hour)
or (employeelabor.clockout >= hourlist.hour
and employeelabor.clockout < dateadd(HH, 1, hourlist.hour)
order by
hourlist.Hour
Upvotes: 0
Views: 151
Reputation: 3266
For requirements like these, it helps to have a helper table. In this case, we will create a little @hours
helper table, load it with 24 hours, and join this to the Timeclock
table to return one record for each employee hour worked:
-- load test data
create table Timeclock(empid int,clockin time,clockout time)
insert into Timeclock values(103,'10:30','12:45')
-- load @hours helper table
declare @hours table (start_time time, end_time time)
declare @hour time = '00:00'
while (select count(*) from @hours) < 24
begin
insert into @hours values(@hour, dateadd(hour,1,@hour))
set @hour = dateadd(hour,1,@hour)
end
-- get minutes worked per hour per empid
select
empid,
datepart(hour,h.start_time) as [hour],
datediff(minute,
case
when t.clockin > h.start_time
then t.clockin
else h.start_time
end,
case
when isnull(t.clockout,getdate()) < h.end_time
then isnull(t.clockout,getdate())
else h.end_time
end) as [minutes_worked]
from Timeclock t
inner join @hours h
on t.clockin < h.end_time
and isnull(t.clockout,getdate()) >= h.start_time
Results:
empid hour minutes_worked
----------- ----------- --------------
103 10 30
103 11 60
103 12 45
SqlFiddle demo: http://sqlfiddle.com/#!6/b92fe/1
Upvotes: 1
Reputation: 207
Can we try like that
declare @tb table
(
empid int,
clockin time(2),
clockout time(2)
)
Insert into @tb (empid, clockin, clockout) VALUES (1, DATEADD(mi, 2, GETDATE()), DATEADD(mi, 20, GETDATE()))
Insert into @tb (empid, clockin, clockout) VALUES (1, DATEADD(mi, -400, GETDATE()), DATEADD(mi, 25, GETDATE()))
Insert into @tb (empid, clockin, clockout) VALUES (1, '11:37:00', '12:37:00')
SELECT *, DATEDIFF(mi, clockin, clockout), CONVERT(varchar(5), DATEADD(minute, DATEDIFF(mi, clockin, clockout), 0), 114) FROM @tb
Upvotes: 0