I want to know if there is a better way to write this sql query, in terms of performance and stability.
Because, I think I'm repeating the code many times and maybe I can do it with the CASE clause or another one.
SELECT x.Fecha,x.IdTrabajador,Cast(x.Cantidad AS DECIMAL(18, 2)) AS Cantidad,x.Motivo,x.IdTrabajadorIncidencia
FROM (SELECT I.IdTrabajador,I.Fecha,
Datediff(second, I.HoraIngreso, (SELECT HD.HoraInicio
FROM [rrhh].TrabajadorHorarioDetalle HD
INNER JOIN [rrhh].TrabajadorHorario H
ON HD.IdTrabajadorHorario = H.IdTrabajadorHorario
WHERE H.Estado = 1
AND HD.Estado = 1
AND HD.Dia = Datename(dw, I.Fecha)
AND H.IdTrabajador = I.IdTrabajador)) / 3600.0 AS Cantidad,
'Sobretiempo en hora de ingreso...' AS Motivo,I.IdTrabajadorIncidencia
FROM [rrhh].TrabajadorIncidencia I
WHERE I.Estado = 1
AND I.IdIncidencia = 1) AS x
WHERE x.Cantidad > 0.00
UNION
SELECT x.Fecha,x.IdTrabajador,Cast(x.Cantidad AS DECIMAL(18, 2)) AS Cantidad,x.Motivo,x.IdTrabajadorIncidencia
FROM (SELECT I.IdTrabajador,I.Fecha,
Datediff(second, (SELECT HD.HoraInicioRefrigerio
FROM [rrhh].TrabajadorHorarioDetalle HD
INNER JOIN [rrhh].TrabajadorHorario H
ON HD.IdTrabajadorHorario = H.IdTrabajadorHorario
WHERE H.Estado = 1
AND HD.Estado = 1
AND HD.Dia = Datename(dw, I.Fecha)
AND H.IdTrabajador = I.IdTrabajador), I.HoraInicioRefrigerio) / 3600.0 AS Cantidad,
'Sobretiempo en hora de inicio de refrigerio...' AS Motivo,I.IdTrabajadorIncidencia
FROM [rrhh].TrabajadorIncidencia I
WHERE I.Estado = 1
AND I.IdIncidencia = 1) AS x
WHERE x.Cantidad > 0.00
UNION
SELECT x.Fecha,x.IdTrabajador,Cast(x.Cantidad AS DECIMAL(18, 2)) AS Cantidad,x.Motivo,x.IdTrabajadorIncidencia
FROM (SELECT I.IdTrabajador,I.Fecha,
Datediff(second, I.HoraFinRefrigerio, (SELECT HD.HoraFinRefrigerio
FROM [rrhh].TrabajadorHorarioDetalle HD
INNER JOIN [rrhh].TrabajadorHorario H
ON HD.IdTrabajadorHorario = H.IdTrabajadorHorario
WHERE H.Estado = 1
AND HD.Estado = 1
AND HD.Dia = Datename(dw, I.Fecha)
AND H.IdTrabajador = I.IdTrabajador)) / 3600.0 AS Cantidad,
'Sobretiempo en hora de término de refrigerio...' AS Motivo,I.IdTrabajadorIncidencia
FROM [rrhh].TrabajadorIncidencia I
WHERE I.Estado = 1
AND I.IdIncidencia = 1) AS x
WHERE x.Cantidad > 0.00
UNION
SELECT x.Fecha,x.IdTrabajador,Cast(x.Cantidad AS DECIMAL(18, 2)) AS Cantidad,x.Motivo,x.IdTrabajadorIncidencia
FROM (SELECT I.IdTrabajador,I.Fecha,
Datediff(second, (SELECT HD.HoraFin
FROM [rrhh].TrabajadorHorarioDetalle HD
INNER JOIN [rrhh].TrabajadorHorario H
ON HD.IdTrabajadorHorario = H.IdTrabajadorHorario
WHERE H.Estado = 1
AND HD.Estado = 1
AND HD.Dia = Datename(dw, I.Fecha)
AND H.IdTrabajador = I.IdTrabajador), I.HoraSalida) / 3600.0 AS Cantidad,
'Sobretiempo en hora de salida...' AS Motivo,I.IdTrabajadorIncidencia
FROM [rrhh].TrabajadorIncidencia I
WHERE I.Estado = 1
AND I.IdIncidencia = 1) AS x
WHERE x.Cantidad > 0.00
UNION
--Search Horas Extras (HE25 y HE35) in table TrabajadorIncidencia
SELECT x.Fecha,x.IdTrabajador,Cast(x.Cantidad AS DECIMAL(18, 2)) AS Cantidad,x.Motivo,x.IdTrabajadorIncidencia
FROM (SELECT I.IdTrabajador,I.Fecha,Datediff(second, I.HoraIngreso, I.HoraSalida) / 3600.0 AS Cantidad,'Sobretiempo en hora extra registrada...' AS Motivo,I.IdTrabajadorIncidencia
FROM [rrhh].TrabajadorIncidencia I
WHERE I.Estado = 1
AND ( I.IdIncidencia = 2
OR I.IdIncidencia = 4 )) AS x
WHERE x.Cantidad > 0.00
ORDER BY x.Fecha;
The previous sql query works fine, but maybe it could be better. Thanks.
UNION? I'm looking, but it's a lot of code and it's not jumping out (aside from the last union)Datediff(in the first four selects)