Aquí está la primera parte:Autos superpuestos por usuario...
SQLFiddle:consulta correlacionada y consulta de combinación
Segunda parte:más de un usuario en un automóvil al mismo tiempo:SQLFiddle:consulta y unión correlacionadas Consulta . Consulta a continuación...
Uso las consultas correlacionadas:
Es probable que necesite índices en ID de usuario y 'automóvil'. Sin embargo, verifique el 'plan de explicación' para ver cómo mysql está accediendo a los datos. E inténtalo :)
Vehículos superpuestos por usuario
La consulta:
SELECT `allCars`.`userid` AS `allCars_userid`,
`allCars`.`car` AS `allCars_car`,
`allCars`.`From` AS `allCars_From`,
`allCars`.`To` AS `allCars_To`,
`allCars`.`tableid` AS `allCars_id`
FROM
`cars` AS `allCars`
WHERE
EXISTS
(SELECT 1
FROM `cars` AS `overlapCar`
WHERE
`allCars`.`userid` = `overlapCar`.`userid`
AND `allCars`.`tableid` <> `overlapCar`.`tableid`
AND NOT ( `allCars`.`From` >= `overlapCar`.`To` /* starts after outer ends */
OR `allCars`.`To` <= `overlapCar`.`From`)) /* ends before outer starts */
ORDER BY
`allCars`.`userid`,
`allCars`.`From`,
`allCars`.`car`;
Los resultados:
allCars_userid allCars_car allCars_From allCars_To allCars_id
-------------- ----------- ------------ ---------- ------------
1 Navara 2015-03-01 2015-03-31 3
1 GTR 2015-03-28 2015-04-30 4
1 Skyline 2015-04-29 2015-05-31 9
2 Aygo 2015-03-01 2015-03-31 7
2 206 2015-03-29 2015-04-30 8
2 Skyline 2015-04-29 2015-05-31 10
¿Por qué funciona? o Cómo lo pienso:
Utilizo la consulta correlacionada para no tener duplicados con los que lidiar y probablemente sea la más fácil de entender para mí. Hay otras formas de expresar la consulta. Cada uno tiene ventajas y desventajas. Quiero algo que pueda entender fácilmente.
Requisito:para cada usuario, asegúrese de que no tengan dos o más automóviles al mismo tiempo.
Entonces, para cada registro de usuario (AllCars) revise la tabla completa (overlapCar) para ver si puede encontrar un diferente registro que se superpone a la hora del registro actual. Si encontramos uno, seleccione el registro actual que estamos comprobando (en allCars).
Por lo tanto, la superposición el cheque es:
-
los
allCars
userid
y eloverLap
userid
debe ser el mismo -
los
allCars
registro del coche y laoverlap
registro de coche debe ser diferente -
los
allCars
rango de tiempo y eloverLap
el intervalo de tiempo debe superponerse.La verificación del intervalo de tiempo:
En lugar de verificar los tiempos superpuestos, use pruebas positivas. El enfoque más fácil es verificar que no se superponga y aplicar un
NOT
a ella.
Un coche con más de un usuario al mismo tiempo...
La consulta:
SELECT `allCars`.`car` AS `allCars_car`,
`allCars`.`userid` AS `allCars_userid`,
`allCars`.`From` AS `allCars_From`,
`allCars`.`To` AS `allCars_To`,
`allCars`.`tableid` AS `allCars_id`
FROM
`cars` AS `allCars`
WHERE
EXISTS
(SELECT 1
FROM `cars` AS `overlapUser`
WHERE
`allCars`.`car` = `overlapUser`.`car`
AND `allCars`.`tableid` <> `overlapUser`.`tableid`
AND NOT ( `allCars`.`From` >= `overlapUser`.`To` /* starts after outer ends */
OR `allCars`.`To` <= `overlapUser`.`From`)) /* ends before outer starts */
ORDER BY
`allCars`.`car`,
`allCars`.`userid`,
`allCars`.`From`;
Los resultados:
allCars_car allCars_userid allCars_From allCars_To allCars_id
----------- -------------- ------------ ---------- ------------
Skyline 1 2015-04-29 2015-05-31 9
Skyline 2 2015-04-29 2015-05-31 10
Editar:
En vista de los comentarios, por @philipxy, sobre los rangos de tiempo que necesitan verificaciones 'mayores o iguales a', actualicé el código aquí. No he cambiado los SQLFiddles
.