Tengo una tabla como la siguiente:
EmpId DateTimeIn DateTimeOut Effort
1030 2016-12-01 07:30:00.000 2016-12-01 12:30:00.000 1030
1030 2016-12-01 13:30:00.000 2016-12-01 16:30:00.000 1531
El empleado 1030
ha insertado su esfuerzo el 2016-12-01 para los rangos de tiempo de 07:30 a 12:30 y de 13:30 a 16:30.
Después de esto, no debe ingresar su esfuerzo en estos rangos de tiempo. Puede ingresar esfuerzo antes de las 7:30 o de 12:30 a 13:30 o después de las 16:30 del 2016-12-01 o puede ingresar cualquier otro día.
Para lograr esto, escribo una consulta a continuación, pero siempre está generando errores y no permite a los usuarios insertar datos. Por favor ayuda.
IF EXISTS (SELECT 1 FROM TimesheetEntries
WHERE EmpId = @EmpId AND (@DateTimeIn >= DateTimeIn AND @DateTimeIn < DateTimeOut)
OR (@DateTimeOut >= DateTimeOut AND @DateTimeOut < DateTimeIn))
BEGIN
RAISERROR ("You already input your effort for the given time range.",16,1)
RETURN
END
Respuestas
2 para la respuesta № 1Una vez encontré que estas expresiones pueden sersimplificado: si se va a detectar una superposición, el tiempo debe transcurrir antes del final de un turno existente con el que se está comparando. Si ese es el caso, entonces el trabajador también debe haber trabajado después del inicio del turno existente. Puede reducirse a dos condiciones clave
IF EXISTS (SELECT 1 FROM TimesheetEntries
WHERE EmpId = @EmpId AND @DateTimeIn < DateTimeOut
AND @DateTimeOut > DateTimeIn) --has to have started before end AND ended after the start
BEGIN
RAISERROR ("You already input your effort for the given time range.",16,1)
RETURN
END
3 para la respuesta № 2
Parece un problema de paréntesis, no estás AND
ambas partes de tu OR
con el EmpId = @EmpId
. También parece que la lógica es ligeramente defectuosa (verifica que @DateTimeOut
es más tarde que DateTimeOut
y antes de DateTimeIn
, que si DateTimeOut > DateTimeIn
como esperábamos, nunca estaremos satisfechos).
Tratar:
IF EXISTS
(
SELECT 1
FROM TimesheetEntries
WHERE EmpId = @EmpId
AND ((@DateTimeIn >= DateTimeIn AND @DateTimeIn <= DateTimeOut) OR (@DateTimeOut >= DateTimeIn AND @DateTimeOut <= DateTimeOut))
)
BEGIN
RAISERROR ("You already input your effort for the given time range.",16,1)
RETURN
END
1 para la respuesta № 3
Esta consulta informará en todas las condiciones y funcionará para su caso.
NOTA: @ 3N1GM4 "s respuesta Es más corto que yo y también funciona para tu caso.
IF EXISTS
(
select TOP 1 1 from HR.TimesheetEntries where SubmittedByEmpId = 1030 AND
(
(DateTimeIn > @DateTimeIn AND DateTimeIn < @DateTimeIn) OR (DateTimeOut > @DateTimeOut AND DateTimeOut < @DateTimeOut) OR
(DateTimeIn > @DateTimeIn AND DateTimeOut < @DateTimeIn) OR (DateTimeOut > @DateTimeOut AND DateTimeIn < @DateTimeOut) OR
(DateTimeOut > @DateTimeIn AND DateTimeIn < @DateTimeIn) OR (DateTimeIn > @DateTimeOut AND DateTimeOut < @DateTimeOut) OR
(DateTimeOut > @DateTimeIn AND DateTimeOut < @DateTimeIn) OR (DateTimeOut > @DateTimeOut AND DateTimeOut < @DateTimeOut)
)
)
BEGIN
RAISERROR ("You already input your effort for the given time range.",16,1)
RETURN
END