Это будет работать, если ваши старты и стопы надежны. Ваш образец имеет два запуска по порядку - начинается 10:00 и 10:30. Я предполагаю, что в процессе производства у вас будет идентификатор сотрудника, и я добавлю его к образцу данных вместо столбца идентификации.
Также на производстве установки CTE будут уменьшены с помощью параметра на дату. Если есть ночные смены, вам нужно, чтобы ваш stops
CTE использовал dateadd(day, 1, @startDate)
в качестве верхней границы при получении даты окончания.
Настройка образца:
declare @temp table (
EmpId int,
TimeStamp datetime,
StartOrStop varchar(55),
TimeCode int
);
insert into @temp
values
(1, '2017-01-01 07:00:00', 'Start', 1),
(1, '2017-01-01 08:15:00', 'Stop', 2),
(1, '2017-01-01 10:00:00', 'Start', 1),
(1, '2017-01-01 11:00:00', 'Stop', 2),
(2, '2017-01-01 10:30:00', 'Start', 1),
(2, '2017-01-01 12:00:00', 'Stop', 2)
Запрос:
;with starts as (
select t.EmpId,
t.TimeStamp as StartTime,
row_number() over (partition by t.EmpId order by t.TimeStamp asc) as rn
from @temp t
where Timecode = 1 --Start time code?
),
stops as (
select t.EmpId,
t.TimeStamp as EndTime,
row_number() over (partition by t.EmpId order by t.TimeStamp asc) as rn
from @temp t
where Timecode = 2 --Stop time code?
)
select cast(min(sub.StartTime) as date) as WorkDay,
sub.EmpId as Employee,
min(sub.StartTime) as ClockIn,
min(sub.EndTime) as ClockOut,
sum(sub.MinutesWorked) as MinutesWorked
from
(
select strt.EmpId,
strt.StartTime,
stp.EndTime,
datediff(minute, strt.StartTime, stp.EndTime) as MinutesWorked
from starts strt
inner join stops stp
on strt.EmpId = stp.EmpId
and strt.rn = stp.rn
)sub
group by sub.EmpId
'select sum (DATEDIFF (MINUTE, @startdate, @enddate)) ....' –
Является ли это одной строкой с началом/остановкой на запись или началом остановки по двум строкам? Если бы вы могли предоставить образцы данных, это было бы намного проще. –
@JorgeCampos - я бы подумал, что 'select DATEDIFF (MINUTE, min (startdate), max (enddate))' будет более эффективным? – Tony