Я бы использовал запрос следующим образом:
select workerid, sum(case
when punchtype = 'in' then -DATEDIFF(MINUTE, '20110901', punchtime)
when punchtype = 'out' then DATEDIFF(MINUTE, '20110901', punchtime)
when punchtype = 'bin' then -DATEDIFF(MINUTE, '20110901', punchtime)
when punchtype = 'bout' then DATEDIFF(MINUTE, '20110901', punchtime)
end )/60 as WorkingHours
from Punchlog
group by workerid
Примечания: Предположим, у меня есть таблица:
create table PunchLog
(workerid int not null,
punchtime datetime not null,
punchtype char(4) not null)
с данными перфорации за несколько дней.
Приведем некоторые данные теста:
insert into PunchLog (workerid, punchtime, punchtype) values (1, '20110901 23:30', 'in')
insert into PunchLog (workerid, punchtime, punchtype) values (1, '20110902 03:30', 'out')
insert into PunchLog (workerid, punchtime, punchtype) values (1, '20110902 00:15', 'bin')
insert into PunchLog (workerid, punchtime, punchtype) values (1, '20110902 01:15', 'bout')
insert into PunchLog (workerid, punchtime, punchtype) values (2, '20110901 09:30', 'in')
insert into PunchLog (workerid, punchtime, punchtype) values (2, '20110901 17:00', 'out')
insert into PunchLog (workerid, punchtime, punchtype) values (2, '20110901 14:30', 'bin')
insert into PunchLog (workerid, punchtime, punchtype) values (2, '20110901 10:00', 'bout')
Время, проведенное на рабочем месте:
T = out - in - (bin -bout) = out - in -bin + bout
, где in
, out
- время дневного удара и bin
, bout
- время пробоя.
Если я сгруппируюсь по workerid
и приложу sum () к punchtime
, тогда у меня будет рабочее время, НО мне нужно, чтобы in
и bin
время были отрицательными.Также я не могу суммировать дату и время.Таким образом, я изменю punchtime
на диапазон от любой даты в прошлом и использую инструкцию case для установки знака:
sum(case
when punchtype = 'in' then -DATEDIFF(MINUTE, '20110901', punchtime)
when punchtype = 'out' then DATEDIFF(MINUTE, '20110901', punchtime)
. . .
end )/60 as WorkingHours
в моем тесте он дает результат:
workerid WorkingHours
-------- ------------
1 5
2 3