Reputation: 5
In SQL Server, how can I get the employee 'in/out' status based on the 'enter/exit' column? For example, if the last record for an employee is 'enter', then he is 'in'. If the last record is 'exit', then he is 'out'. For id=111, the in_out should be 'in', and id=222 should be 'out'
+-----+---------------------+------------+
| id | timestamp | status |
+-----+---------------------+------------+
| 111 | 01/01/2017 07:00:10 | enter |
| 222 | 01/01/2017 01:10:29 | enter |
| 111 | 01/01/2017 18:20:17 | exit |
| 111 | 01/02/2017 08:20:34 | enter |
| 333 | 01/02/2017 06:20:11 | enter |
| 222 | 01/02/2017 10:10:47 | exit |
+-----+---------------------+------------+
I understand I should use case statement, but the following code won't work
select id, case
when status = 'enter' then 'in'
when status = 'exit' then 'out'
else 'n/a'
end as in_out
from table1
Upvotes: 0
Views: 366
Reputation: 7837
The trick is to find the first exit following each enter.
select in.id,
case coalesce(min(out.status), in.status)
when 'enter' then 'in'
when 'exit' then 'out'
else 'n/a' -- I suggest: coalesce(out.status, in.status) + '??'
end as 'status'
from table1 as in
left
join table1 as out
on in.id = out.id
and in.timestamp <= out.timestamp
and in.status = 'enter'
and out.status = 'exit'
group by in.id, in.status
This query finds the minimum exit for each {id, timestamp} enter pair. It assumes there's no exit before enter (no one in the building). That requires separate validation.
Whenever I munge the data for a report like this, I try not to squelch unexpected input, but rather let it flow through. If you turn everything that's not enter or exit into n/a, at some point you're going to have to find out what's producing those n/a's. Might as well print it out in the report; it will make your job easier.
Upvotes: 0
Reputation: 13969
If I understand correctly you can query as below:
Select Id, case when [status] = 'enter' then 'in' else 'out' end as In_out
from (
Select *, RowN = row_number() over(partition by id order by [timestamp] desc) from #timedata
) a Where a.RowN = 1
Output as below:
+-----+--------+
| Id | In_out |
+-----+--------+
| 111 | in |
| 222 | out |
| 333 | in |
+-----+--------+
Upvotes: 1