¿Cómo agrupar a los empleados en rangos de horas?
Frecuentes
Visto 117 veces
1
Tengo esta mesa para ahorrar el tiempo que los empleados pasan haciendo una tarea rutinaria.
CREATE TABLE tasks (
id INT NOT NULL PRIMARY KEY,
name VARCHAR(100),
date_task date,
time_ini time,
time_end time
);
- Estoy tratando de agrupar a los empleados que tienen al menos dos time_ini con una diferencia < 15 minutos con el time_ini o time_end de cualquier empleado.
- Si ninguno de sus time_ini cumple con esta condición, entonces este empleado se agruparía solo.
- Los grupos estarán numerados del 1 al n.
- Y luego se ordenarán los grupos por fecha ascendente, y time_ini ascendente.
Este es un ejemplo de datos:
(1, "oscar", '2012-01-01', '01:30', '01:32'),
(2, "oscar", '2012-01-01', '02:30', '02:32'),
(3, "oscar", '2012-01-01', '05:30', '05:32'),
(4, "oscar", '2012-01-01', '06:30', '06:32'),
(5, "mario", '2012-01-01', '02:43', '02:43'),
(6, "mario", '2012-01-01', '02:53', '02:53'),
(7, "mario", '2012-01-01', '05:30', '05:30'),
(8, "martah", '2012-01-01', '01:25', '01:28'),
(9, "martah", '2012-01-01', '02:29', '02:41'),
(10, "jesus", '2012-01-01', '01:25', '01:28'),
(11, "jesus", '2012-01-01', '01:25', '02:28'),
(12, "jesus", '2012-01-01', '07:33', '08:32'),
(13, "jesus", '2012-01-01', '07:35', '07:36'),
(14, "jesus", '2012-01-01', '08:36', '08:39'),
(15, "rober", '2012-01-01', '02:43', '02:46'),
(16, "rober", '2012-01-01', '02:56', '03:00'),
(17, "rober", '2012-01-01', '02:29', '11:32'),
(18, "pedro", '2012-01-01', '11:36', '12:46'),
(19, "pedro", '2012-01-01', '12:36', '16:46');
Este sería el resultado:
GROUP NAME
1 oscar
1 marta
1 jesus
2 mario
2 rober
3 pedro
Se me ocurrió algo como esto:
select distinct a.name
from tasks a
where
(select count(id)
from tasks b
where (
MINUTE(TIMEDIFF(a.time_ini, b.time_ini)) < 15 OR
MINUTE(TIMEDIFF(a.time_end, b.time_ini)) < 15
) and
b.name <> a.name) >= 2;
Me temo que no puedo agruparlos de esta manera, pero creo que no estoy demasiado lejos de la solución, ¿no es así?
Cualquier idea, sugerencia o consejo será apreciado, y si necesita más información, hágamelo saber y editaré la publicación. Es un poco dificil de explicar...
1 Respuestas
1
Puede probar esto (aunque no está en el formato que necesita... debería hacer el trabajo):
SELECT
a.id as groupId,
a.name as first,
b.name as second,
COUNT(*) as occ
FROM
tasks a,task b
WHERE
b.name <> a.name
AND a.id > b.id
AND (
MINUTE(TIMEDIFF(a.date_ini, b.date_ini)) < 15 OR
MINUTE(TIMEDIFF(a.date_end, b.date_ini)) < 15
)
GROUP BY
groupId,
first,
second
IVA jesus
debería estar en el grupo con oscar
y martha
debido a los registros 10 y 11
Respondido el 02 de diciembre de 13 a las 09:12
¡Gracias! Funciona, pero ¿podría intentar generar la salida con el formato que estoy tratando de obtener, por favor? Este es mi principal problema. - mllamazares
¿Siempre ocurre que a.date_end - a.date_ini < 30 minutos? Y observo que date_end no siempre es > date_ini !?! Ah, ¿y las tareas pueden superponerse con las fechas? - Strawberry
La diferencia entre time_end y time_ini no siempre será de 30 minutos. Construí estos datos solo para el ejemplo. Y time_end debe ser >= time_ini, lo siento, he editado la publicación. Y las tareas no pueden superponerse en fechas. Gracias por tu interés. - mllamazares
Entonces, si lo entendí bien, entonces realmente está interesado en cualquier time_ini que ocurra "ENTRE x.time_ini - 15 INTERVALO 15 MINUTO Y x.time_end + INTERVALO 15 MINUTO", ¿verdad? - Strawberry
Nop, intento agrupar usando la siguiente condición: (a.time_ini between b.time_ini + - 15 mins) OR (a.time_ini between b.time_end + - 15 mins). ¡Gracias! - mllamazares