Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 How to get the time spent inside and outside

Author  Topic 

milo1981
Starting Member

18 Posts

Posted - 2014-03-26 : 06:06:49
I have a simple table (SQL Server 2005) which stores employees clock-ins and clock-outs throughout the day:

+------------------------------------------+
¦ Employee ¦ PunchDateTime ¦ ActionType ¦
¦----------+------------------+------------¦
¦ John ¦ 2014/03/26 08:00 ¦ IN ¦
¦ Mark ¦ 2014/03/26 08:12 ¦ IN ¦
¦ John ¦ 2014/03/26 08:50 ¦ OUT ¦
¦ John ¦ 2014/03/26 09:29 ¦ IN ¦
¦ Mark ¦ 2014/03/26 10:35 ¦ OUT ¦
¦ John ¦ 2014/03/26 10:55 ¦ OUT ¦
¦ Mark ¦ 2014/03/26 11:42 ¦ IN ¦
¦ John ¦ 2014/03/26 12:38 ¦ IN ¦
¦ John ¦ 2014/03/26 16:21 ¦ OUT ¦
¦ Mark ¦ 2014/03/26 16:49 ¦ OUT ¦
+------------------------------------------+

I want build a query that calculates time spent in and out. The end result should look like this:
+-------------------------------------------------------------+
¦ Employee ¦ PunchDateTime ¦ ActionType ¦ TimeIn ¦ TimeOut ¦
¦----------+------------------+------------+--------+---------¦
¦ John ¦ 2014/03/26 08:00 ¦ IN ¦ - ¦ - ¦
¦ Mark ¦ 2014/03/26 08:12 ¦ IN ¦ - ¦ - ¦
¦ John ¦ 2014/03/26 08:50 ¦ OUT ¦ 00:40 ¦ - ¦
¦ John ¦ 2014/03/26 09:29 ¦ IN ¦ - ¦ 00:39 ¦
¦ Mark ¦ 2014/03/26 10:35 ¦ OUT ¦ 02:23 ¦ - ¦
¦ John ¦ 2014/03/26 10:55 ¦ OUT ¦ 01:26 ¦ - ¦
¦ Mark ¦ 2014/03/26 11:42 ¦ IN ¦ - ¦ 01:07 ¦
¦ John ¦ 2014/03/26 12:05 ¦ IN ¦ - ¦ 01:10 ¦
¦ John ¦ 2014/03/26 16:21 ¦ OUT ¦ 04:16 ¦ - ¦
¦ Mark ¦ 2014/03/26 16:49 ¦ OUT ¦ 05:07 ¦ - ¦
+-------------------------------------------------------------+

I need the total time spent IN and total time spent OUT, for each day.

The time spent will be calculated only for valid pairs of INs and OUTs, eliminating those that can't be paired (two or more consecutive INs/OUTs).

The results need to be by user, per one day. If the interval is longer than one day, the total time spent must be calculated for each day.

sz1
Aged Yak Warrior

555 Posts

Posted - 2014-03-26 : 07:48:07
There are no column ID fields so assuming your Employee name will always stay unique and no other same name will be added...you should be ok, you have 00:40 for John but he clocked in at 08:00 and clocked out at 08:50 which = 00:50, where are you getting your 00:40?

We are the creators of our own reality!
Go to Top of Page

milo1981
Starting Member

18 Posts

Posted - 2014-03-26 : 08:28:37
quote:
Originally posted by sz1

There are no column ID fields so assuming your Employee name will always stay unique and no other same name will be added...you should be ok, you have 00:40 for John but he clocked in at 08:00 and clocked out at 08:50 which = 00:50, where are you getting your 00:40?

We are the creators of our own reality!



The Employee name will always stay unique.

It's a calculation mistake, it shoul be 00:50.
Go to Top of Page

sz1
Aged Yak Warrior

555 Posts

Posted - 2014-03-26 : 09:01:03
I don't have the data to test but something along the lines of this:

Declare @PDTime as Time
Declare @PDDate as Date
Set @PDTime = PunchDateTime
Set @PDDate = PunchDateTime

Select
Employee,
Convert(Varchar(10),PunchDateTime,105) 'PunchDateTime',
ActionType,
TimeIn = Case
When ActionType = 'IN'
Then @PDTime
Else 'None'
End,
TimeOut = Case
When ActionType = 'OUT'
Then @PDTime
Else 'None'
End,
Sum(@PDTime) as TotalTime
Where Employee = Employee
And @PDDate = @PDDate

GO

We are the creators of our own reality!
Go to Top of Page

milo1981
Starting Member

18 Posts

Posted - 2014-03-26 : 10:04:20
This is what i have from another forum:

if object_id('tempdb..#Punch') is not null
drop table #Punch

create table #Punch(
Employee varchar(50) not null,
PunchDateTime datetime not null,
ActionType varchar(3) not null
)

insert into #Punch select 'John', '2014-03-26 05:30:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 05:36:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 06:24:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:42:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 06:43:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:52:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:53:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:54:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:55:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 08:46:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 08:52:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 10:08:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 10:12:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 10:22:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 10:24:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 16:48:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 16:57:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 17:04:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 17:07:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 17:09:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 17:10:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 17:15:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 17:16:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 17:17:00.000', 'IN'

select *
from (
select
p.Employee,
p.PunchDateTime,
p.ActionType,
case when p.ActionType = 'IN'
then '-'
else coalesce(substring(convert(varchar(30), p.PunchDateTime - p.PreviousPunchDateTime, 20), 12, 5), '-')
end as TimeIn,
case when p.ActionType = 'OUT'
then '-'
else coalesce(substring(convert(varchar(30), p.PunchDateTime - p.PreviousPunchDateTime, 20), 12, 5), '-')
end as TimeOut
from (
select
a.Employee,
a.PunchDateTime,
a.ActionType,
(
select top 1 b.PunchDateTime
from #Punch b
where b.Employee = a.Employee
and b.PunchDateTime < a.PunchDateTime
and b.ActionType <> a.ActionType
and datediff(day, b.PunchDateTime, a.PunchDateTime) = 0 -- same day
and not exists(
select 1
from #Punch c
where c.Employee = a.Employee
and c.ActionType = a.ActionType
and c.PunchDateTime < a.PunchDateTime
and c.PunchDateTime > b.PunchDateTime
)
and not (
b.ActionType = 'OUT'
and not exists(select 1 from #Punch d where d.Employee = a.Employee and d.ActionType = 'IN' and d.PunchDateTime < b.PunchDateTime)
)
order by b.PunchDateTime asc
) as PreviousPunchDateTime
from #Punch a
) p
) p2
where not (p2.ActionType = 'OUT' and p2.TimeIn = '-' and p2.TimeOut = '-')
and not (
p2.ActionType = 'IN' and p2.TimeIn = '-' and p2.TimeOut = '-'
and exists(select 1 from #Punch a where a.ActionType = 'IN' and a.Employee = p2.Employee and a.PunchDateTime < p2.PunchDateTime))
order by
p2.PunchDateTime



The results need to be by user, per one day. If the interval is longer than one day, the total time spent must be calculated for each day
Double ins/outs will be disregarded, outermost should be used (so in,in,out means track time from the first in to the out)
I need only daily results. If the employee enters at the end of the day, and exits the next day, it will be ignored. Starting from the first valid IN and last valid OUT.
The time spent will be calculated only for valid pairs of INs and OUTs, eliminating those that can't be paired (two or more consecutive INs/OUTs)

How it how the data should be processed:
[url]http://postimg.org/image/wye0xtmkh/[/url]

It calculates correctly the TimeIn, but not the TimeOut (it doesn't discard the IN at 10:24, instead it wrongly discards the one at 16:48).
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2014-03-26 : 11:08:57
quote:
outermost should be used (so in,in,out means track time from the first in to the out)

You stated outermost, but in the image, you have following, if taking outermost, it should be taking 6:54 as OUT

06:42 IN
06:43 OUT
06:52 OUT Discard
06:53 OUT Discard
06:54 OUT Discard


please confirm



KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

milo1981
Starting Member

18 Posts

Posted - 2014-03-27 : 02:37:58
This is what I want to be discarded:

00:01 OUT
00:02 IN Discard
00:03 IN Discard
00:04 IN
00:05 OUT
00:06 OUT Discard
00:07 OUT Discard
00:08 IN

If you have OUT,IN,IN,IN means track time from the first OUT to the last IN
If you have OUT,OUT,OUT,IN means track time from the first OUT to the last IN
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2014-03-27 : 03:32:17
[code]if object_id('tempdb..#Punch') is not null drop table #Punch

create table #Punch
(
Employee varchar(10) not null,
PunchDateTime datetime not null,
ActionType varchar(3) not null
)

insert into #Punch select 'John', '2014-03-26 05:30:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 05:36:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 06:24:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:42:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 06:43:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:52:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:53:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:54:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:55:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 08:46:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 08:52:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 10:08:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 10:12:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 10:22:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 10:24:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 16:48:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 16:57:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 17:04:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 17:07:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 17:09:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 17:10:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 17:15:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 17:16:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 17:17:00.000', 'IN'

; with punch as
(
select Employee,
row_no = row_number() over (partition by Employee order by PunchDateTime),
PunchDateTime,
ActionType
from #Punch
),
punch2 as
(
select c.Employee, row_no = row_number() over (partition by c.Employee order by c.row_no),
c.PunchDateTime, c.ActionType
from punch c
inner join punch p on c.Employee = p.Employee
and c.row_no = p.row_no + 1
inner join punch n on c.Employee = n.Employee
and c.row_no = n.row_no - 1
where (c.ActionType = 'IN' and n.ActionType = 'OUT')
or (c.ActionType = 'OUT' and p.ActionType = 'IN')
)
select c.*,
TimeIn = case when c.ActionType = 'OUT'
then isnull(convert(varchar(5), dateadd(minute, datediff(minute, p.PunchDateTime, c.PunchDateTime), 0), 108), '-')
else '-'
end,
TimeOut = case when c.ActionType = 'IN'
then isnull(convert(varchar(5), dateadd(minute, datediff(minute, p.PunchDateTime, c.PunchDateTime), 0), 108), '-')
else '-'
end
from punch2 c
left join punch2 p on c.Employee = p.Employee
and c.row_no = p.row_no + 1
order by c.Employee, c.row_no

/*
Employee row_no PunchDateTime ActionType TimeIn TimeOut
---------- -------------------- ------------------------ ---------- ------ -------
John 1 2014-03-26 05:36:00.000 IN - -
John 2 2014-03-26 06:24:00.000 OUT 00:48 -
John 3 2014-03-26 06:42:00.000 IN - 00:18
John 4 2014-03-26 06:43:00.000 OUT 00:01 -
John 5 2014-03-26 06:55:00.000 IN - 00:12
John 6 2014-03-26 08:46:00.000 OUT 01:51 -
John 7 2014-03-26 08:52:00.000 IN - 00:06
John 8 2014-03-26 10:08:00.000 OUT 01:16 -
John 9 2014-03-26 10:12:00.000 IN - 00:04
John 10 2014-03-26 10:22:00.000 OUT 00:10 -
John 11 2014-03-26 16:48:00.000 IN - 06:26
John 12 2014-03-26 16:57:00.000 OUT 00:09 -
John 13 2014-03-26 17:04:00.000 IN - 00:07
John 14 2014-03-26 17:07:00.000 OUT 00:03 -
John 15 2014-03-26 17:09:00.000 IN - 00:02
John 16 2014-03-26 17:10:00.000 OUT 00:01 -
John 17 2014-03-26 17:15:00.000 IN - 00:05
John 18 2014-03-26 17:16:00.000 OUT 00:01 -

(18 row(s) affected)

*/[/code]


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

milo1981
Starting Member

18 Posts

Posted - 2014-03-27 : 05:19:00
Thank you!
Now, it works great when calculating TimeIn and TimeOut!

But..
There is a problem with the last IN record at '2014-03-26 17:17:00.000'.
Being an unpaired record, it should be discarded, like it did with first OUT record at '2014-03-26 05:30:00.000'

Also, how can I get the total TimeIn and total TimeOut for a given date interval and a given employee name?
If the interval date is more than one day, the totals should be calculated for each day.
The calculation shoul be done only for valid pairs of IN-OUT.
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2014-03-27 : 05:27:25
quote:
Originally posted by milo1981

Thank you!
Now, it works great when calculating TimeIn and TimeOut!

But..
There is a problem with the last IN record at '2014-03-26 17:17:00.000'.
Being an unpaired record, it should be discarded, like it did with first OUT record at '2014-03-26 05:30:00.000'



You mean my query will show that last IN record ?


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

milo1981
Starting Member

18 Posts

Posted - 2014-03-27 : 05:35:24
Sorry, my mistake! I run it on a different table on data.

How can I get the total TimeIn and total TimeOut for a given date interval and a given employee name?
If the interval date is more than one day, the totals should be calculated for each day.
The calculation shoul be done only for valid pairs of IN-OUT.
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2014-03-27 : 05:47:38
Note the changes in red
if object_id('tempdb..#Punch') is not null drop table #Punch

create table #Punch
(
Employee varchar(10) not null,
PunchDateTime datetime not null,
ActionType varchar(3) not null
)

insert into #Punch select 'John', '2014-03-26 05:30:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 05:36:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 06:24:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:42:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 06:43:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:52:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:53:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:54:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:55:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 08:46:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 08:52:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 10:08:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 10:12:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 10:22:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 10:24:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 16:48:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 16:57:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 17:04:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 17:07:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 17:09:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 17:10:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 17:15:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 17:16:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 17:17:00.000', 'IN'
insert into #Punch select 'John', '2014-03-27 08:01:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-27 09:15:00.000', 'IN'
insert into #Punch select 'John', '2014-03-27 09:26:00.000', 'OUT'


-- Detail Query
; with punch as
(
select Employee,
row_no = row_number() over (partition by Employee, dateadd(day, datediff(day, 0, PunchDateTime), 0)
order by PunchDateTime),
PunchDate = dateadd(day, datediff(day, 0, PunchDateTime), 0),

PunchDateTime,
ActionType
from #Punch
),
punch2 as -- Valid pairs of IN-OUT
(
select c.Employee,
row_no = row_number() over (partition by c.Employee, c.PunchDate order by c.row_no),
c.PunchDate, c.PunchDateTime, c.ActionType
from punch c
left join punch p on c.Employee = p.Employee
and c.PunchDate = p.PunchDate

and c.row_no = p.row_no + 1
left join punch n on c.Employee = n.Employee
and c.PunchDate = n.PunchDate

and c.row_no = n.row_no - 1
where (c.ActionType = 'IN' and n.ActionType = 'OUT')
or (c.ActionType = 'OUT' and p.ActionType = 'IN')
)
select c.*,
TimeIn = case when c.ActionType = 'OUT'
then isnull(convert(varchar(5), dateadd(minute, datediff(minute, p.PunchDateTime, c.PunchDateTime), 0), 108), '-')
else '-'
end,
TimeOut = case when c.ActionType = 'IN'
then isnull(convert(varchar(5), dateadd(minute, datediff(minute, p.PunchDateTime, c.PunchDateTime), 0), 108), '-')
else '-'
end
from punch2 c
left join punch2 p on c.Employee = p.Employee
and c.PunchDate = p.PunchDate

and c.row_no = p.row_no + 1
order by c.Employee, c.PunchDate, c.row_no

-- Summary by Employee & Date
; with punch as
(
select Employee,
row_no = row_number() over (partition by Employee, dateadd(day, datediff(day, 0, PunchDateTime), 0)
order by PunchDateTime),
PunchDate = dateadd(day, datediff(day, 0, PunchDateTime), 0),
PunchDateTime,
ActionType
from #Punch
),
punch2 as
(
select c.Employee,
row_no = row_number() over (partition by c.Employee, c.PunchDate order by c.row_no),
c.PunchDate, c.PunchDateTime, c.ActionType
from punch c
left join punch p on c.Employee = p.Employee
and c.PunchDate = p.PunchDate
and c.row_no = p.row_no + 1
left join punch n on c.Employee = n.Employee
and c.PunchDate = n.PunchDate
and c.row_no = n.row_no - 1
where (c.ActionType = 'IN' and n.ActionType = 'OUT')
or (c.ActionType = 'OUT' and p.ActionType = 'IN')
)
select c.Employee, c.PunchDate,
TimeIn = sum(case when c.ActionType = 'OUT'
then datediff(minute, p.PunchDateTime, c.PunchDateTime)
end),
TimeOut = sum(case when c.ActionType = 'IN'
then datediff(minute, p.PunchDateTime, c.PunchDateTime)
end)
from punch2 c
left join punch2 p on c.Employee = p.Employee
and c.PunchDate = p.PunchDate
and c.row_no = p.row_no + 1
group by c.Employee, c.PunchDate
order by c.Employee, c.PunchDate



Employee row_no PunchDate PunchDateTime ActionType TimeIn TimeOut
---------- ------- ----------- ----------------- ---------- ------ -------
John 1 2014-03-26 2014-03-26 05:36 IN - -
John 2 2014-03-26 2014-03-26 06:24 OUT 00:48 -
John 3 2014-03-26 2014-03-26 06:42 IN - 00:18
John 4 2014-03-26 2014-03-26 06:43 OUT 00:01 -
John 5 2014-03-26 2014-03-26 06:55 IN - 00:12
John 6 2014-03-26 2014-03-26 08:46 OUT 01:51 -
John 7 2014-03-26 2014-03-26 08:52 IN - 00:06
John 8 2014-03-26 2014-03-26 10:08 OUT 01:16 -
John 9 2014-03-26 2014-03-26 10:12 IN - 00:04
John 10 2014-03-26 2014-03-26 10:22 OUT 00:10 -
John 11 2014-03-26 2014-03-26 16:48 IN - 06:26
John 12 2014-03-26 2014-03-26 16:57 OUT 00:09 -
John 13 2014-03-26 2014-03-26 17:04 IN - 00:07
John 14 2014-03-26 2014-03-26 17:07 OUT 00:03 -
John 15 2014-03-26 2014-03-26 17:09 IN - 00:02
John 16 2014-03-26 2014-03-26 17:10 OUT 00:01 -
John 17 2014-03-26 2014-03-26 17:15 IN - 00:05
John 18 2014-03-26 2014-03-26 17:16 OUT 00:01 -
John 1 2014-03-27 2014-03-27 09:15 IN - -
John 2 2014-03-27 2014-03-27 09:26 OUT 00:11 -

Employee PunchDate TimeIn TimeOut
---------- ----------- ----------- -----------
John 2014-03-26 260 440
John 2014-03-27 11 NULL



KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

milo1981
Starting Member

18 Posts

Posted - 2014-03-27 : 06:12:33
Can you explain to me, what does the new PunchDate column does?

I need the totals in HH:mm:ss format so, I've modified this lines:
then isnull(convert(varchar(5), dateadd(minute, datediff(minute, p.PunchDateTime, c.PunchDateTime), 0), 108), '-')
into:
then isnull(convert(varchar(8), dateadd(second, datediff(second, p.PunchDateTime, c.PunchDateTime), 0), 108), '-')

How can I do the same for:
datediff(minute, p.PunchDateTime, c.PunchDateTime)

LATER EDIT:
Nevermind, I got it:
CONVERT(varchar, DATEADD(ss, sum(case when c.Actiune = 'OUT' then datediff(second, p.DataOra, c.DataOra) end), 0), 108)

Thank you!
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2014-03-27 : 07:13:55
quote:
Originally posted by milo1981

Can you explain to me, what does the new PunchDate column does?



PunchDate contains only the date portion of the PuncDateTime, with the time portion is 00:00:00.


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

milo1981
Starting Member

18 Posts

Posted - 2014-03-27 : 08:11:30
I need a adapted version of the script above for the following situation:

Some employees work the nightshift, so, for example, they enter on 27.03 23:00:00 and exit at 28:03 05:00:00. A valid pair of IN-OUT will be considered, and IN from 27.03 and an OUT from 28.03. The total TimeIn and TimeOut per employee will be a sum of TimeIns and TimeOuts from a given interval using the rule explained above.
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2014-03-27 : 08:20:00
use the last query, remove the PunchDate

and this part

row_number() over (partition by Employee, dateadd(day, datediff(day, 0, PunchDateTime), 0)
order by PunchDateTime)



KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2014-03-27 : 08:22:53
[code]if object_id('tempdb..#Punch') is not null drop table #Punch

create table #Punch
(
Employee varchar(10) not null,
PunchDateTime datetime not null,
ActionType varchar(3) not null
)

insert into #Punch select 'John', '2014-03-26 05:30:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 05:36:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 06:24:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:42:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 06:43:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:52:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:53:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:54:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 06:55:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 08:46:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 08:52:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 10:08:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 10:12:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 10:22:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 10:24:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 16:48:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 16:57:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 17:04:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 17:07:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 17:09:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 17:10:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 17:15:00.000', 'IN'
insert into #Punch select 'John', '2014-03-26 17:16:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-26 23:17:00.000', 'IN'
insert into #Punch select 'John', '2014-03-27 08:01:00.000', 'OUT'
insert into #Punch select 'John', '2014-03-27 09:15:00.000', 'IN'
insert into #Punch select 'John', '2014-03-27 09:26:00.000', 'OUT'

-- Detail Query
; with punch as
(
select Employee,
row_no = row_number() over (partition by Employee order by PunchDateTime),
PunchDateTime,
ActionType
from #Punch
),
punch2 as
(
select c.Employee,
row_no = row_number() over (partition by c.Employee order by c.row_no),
c.PunchDateTime, c.ActionType
from punch c
left join punch p on c.Employee = p.Employee
and c.row_no = p.row_no + 1
left join punch n on c.Employee = n.Employee
and c.row_no = n.row_no - 1
where (c.ActionType = 'IN' and n.ActionType = 'OUT')
or (c.ActionType = 'OUT' and p.ActionType = 'IN')
)
select c.*,
TimeIn = case when c.ActionType = 'OUT'
then isnull(convert(varchar(5), dateadd(minute, datediff(minute, p.PunchDateTime, c.PunchDateTime), 0), 108), '-')
else '-'
end,
TimeOut = case when c.ActionType = 'IN'
then isnull(convert(varchar(5), dateadd(minute, datediff(minute, p.PunchDateTime, c.PunchDateTime), 0), 108), '-')
else '-'
end
from punch2 c
left join punch2 p on c.Employee = p.Employee
and c.row_no = p.row_no + 1
order by c.Employee, c.row_no

Employee row_no PunchDateTime ActionType TimeIn TimeOut
---------- ------- -------------------- ---------- ------ -------
John 1 2014-03-26 05:36:00 IN - -
John 2 2014-03-26 06:24:00 OUT 00:48 -
John 3 2014-03-26 06:42:00 IN - 00:18
John 4 2014-03-26 06:43:00 OUT 00:01 -
John 5 2014-03-26 06:55:00 IN - 00:12
John 6 2014-03-26 08:46:00 OUT 01:51 -
John 7 2014-03-26 08:52:00 IN - 00:06
John 8 2014-03-26 10:08:00 OUT 01:16 -
John 9 2014-03-26 10:12:00 IN - 00:04
John 10 2014-03-26 10:22:00 OUT 00:10 -
John 11 2014-03-26 16:48:00 IN - 06:26
John 12 2014-03-26 16:57:00 OUT 00:09 -
John 13 2014-03-26 17:04:00 IN - 00:07
John 14 2014-03-26 17:07:00 OUT 00:03 -
John 15 2014-03-26 17:09:00 IN - 00:02
John 16 2014-03-26 17:10:00 OUT 00:01 -
John 17 2014-03-26 17:15:00 IN - 00:05
John 18 2014-03-26 17:16:00 OUT 00:01 -
John 19 2014-03-26 23:17:00 IN - 06:01
John 20 2014-03-27 08:01:00 OUT 08:44 -
John 21 2014-03-27 09:15:00 IN - 01:14
John 22 2014-03-27 09:26:00 OUT 00:11 -
[/code]


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

milo1981
Starting Member

18 Posts

Posted - 2014-03-27 : 08:46:20
And if I want a summary (total TimeIn and TimeOut) on the whole interval (not on a day to day bases like before) for the second scenario?
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2014-03-27 : 09:03:20
the CTE part is the same as the last one

select	c.Employee, 
TimeIn = sum(case when c.ActionType = 'OUT'
then datediff(minute, p.PunchDateTime, c.PunchDateTime)
end),
TimeOut = sum(case when c.ActionType = 'IN'
then datediff(minute, p.PunchDateTime, c.PunchDateTime)
end)
from punch2 c
left join punch2 p on c.Employee = p.Employee
and c.row_no = p.row_no + 1
group by c.Employee
order by c.Employee



KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

milo1981
Starting Member

18 Posts

Posted - 2014-03-27 : 09:31:50
Where do I insert the WHERE clause to set the interval?
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2014-03-27 : 09:50:02
in the punch CTE

; with punch as
(
select Employee,
row_no = row_number() over (partition by Employee order by PunchDateTime),
PunchDateTime,
ActionType
from #Punch
where PunchDateTime >= @StartDate
and PunchDateTime < @EndDate

),



KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page
    Next Page

- Advertisement -