Dentro del conjunto de funciones que estoy habilitando para un control de producción, se me da el caso de consultar las horas de trabajo diario por empleado.

La tabla de apuntes es un registro de los movimientos que hace cada empleado, al igual que un control de entrada salida de horario. En este caso es un control de tareas de invernadero. Se genera un registro por cada cambio en una tarea, a modo de trazabilidad. Este movimiento incluye la fecha y hora del momento en el que se hace, además del estado en el que se encuentre la tarea, con lo que sumando los movimientos relacionados con la misma tarea, tenemos el total de horas diarias por tarea para un empleado determinado (que sumadas todas dan el total de la jornada).

Partimos de que se está implementando para una plataforma web, por lo que podemos procesar en el servidor y generar la salida html adecuada para mostrar la información.

Pero con tal hacerlo lo mas eficiente posible (ya que se preveen gran cantidad de registros y movimientos) decido hacerlo en un procedimiento almacenado que genere la salida justa para mostarrlo en pantalla.

Dado que el estado es determinante para definir cuando se deja de contar tiempo a una tarea (pues su estado indica que si se ha acabado o no), ésta columna iba a ser un dato a mantener.

el siguiente procedimiento nos da el total de horas de cada trabajador, segun la fecha de consulta

[sourcecode language=»sql»]

CREATE PROCEDURE [spTiempoTrabajoDia]
@FECHA_CONSULTA datetime
AS

–variables control
DECLARE @idsujeto nvarchar(10)
DECLARE @hora time(0)
DECLARE @estado int

–variables para mantener estados
DECLARE @aux_estado int
DECLARE @aux_time time(0)
DECLARE @aux_time_total int = 0

declare @empleado nvarchar(10)
set @empleado = »

–tabla temporal para almacenar los valores
DECLARE @tab table (sujeto nvarchar(10), tiempo int)

DECLARE hcursor CURSOR FOR
select idsujeto,estado,hora from historico_tareas h where fecha=@FECHA_CONSULTA group by idsujeto,estado,hora

OPEN hcursor

FETCH NEXT FROM hcursor
INTO @idsujeto,@estado, @hora

WHILE @@FETCH_STATUS = 0
BEGIN

–recorremos por cada empleado para el dia consultado
IF @estado=1
begin
set @aux_time = @hora
end
else
begin
set @aux_time_total = @aux_time_total + datediff(ss,@aux_time,@hora)
end

–detectamos aqui el cambio de empleado, para reiniciar los valores
IF @empleado<>@idsujeto
BEGIN
IF @aux_time_total<>0
begin
insert @tab SELECT @empleado,@aux_time_total / 3600
end
set @empleado = @idsujeto
set @aux_time_total = 0
END

FETCH NEXT FROM hcursor
INTO @idsujeto, @estado, @hora
END

CLOSE hcursor;
DEALLOCATE hcursor;

–finalmente enviamos el resultado

insert @tab SELECT @empleado,@aux_time_total / 3600
select * from @tab
RETURN

[/sourcecode]