Voici la première partie :Chevauchement de voitures par utilisateur...
SQLFiddle - requête corrélée et requête de jointure
Deuxième partie - plus d'un utilisateur dans une voiture en même temps :SQLFiddle - requête et jointure corrélées Requête . Requête ci-dessous...
J'utilise les requêtes corrélées :
Vous aurez probablement besoin d'index sur userid et 'car'. Cependant - veuillez vérifier le "plan d'explication" pour voir comment mysql accède aux données. Et essayez-le :)
Voitures qui se chevauchent par utilisateur
La requête :
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`;
Les résultats :
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
Pourquoi ça marche ? ou Comment j'y pense :
J'utilise la requête corrélée pour ne pas avoir de doublons à gérer et c'est probablement la plus facile à comprendre pour moi. Il existe d'autres façons d'exprimer la requête. Chacun a des avantages et des inconvénients. Je veux quelque chose que je peux facilement comprendre.
Exigence :pour chaque utilisateur, assurez-vous qu'il n'a pas deux voitures ou plus en même temps.
Ainsi, pour chaque enregistrement d'utilisateur (AllCars) vérifiez le tableau complet (overlapCar) pour voir si vous pouvez trouver un différent enregistrement qui se chevauche pour le temps de l'enregistrement en cours. Si nous en trouvons un, sélectionnez l'enregistrement actuel que nous vérifions (dans allCars).
Par conséquent, le chevauchement le chèque est :
-
le
allCars
userid
et leoverLap
userid
doit être le même -
le
allCars
dossier de voiture et leoverlap
l'enregistrement de la voiture doit être différent -
le
allCars
plage de temps et leoverLap
la plage de temps doit se chevaucher.La vérification de la plage horaire :
Au lieu de vérifier les temps qui se chevauchent, utilisez des tests positifs. L'approche la plus simple consiste à vérifier qu'il ne se chevauche pas et à appliquer un
NOT
à elle.
Une voiture avec plusieurs utilisateurs en même temps...
La requête :
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`;
Les résultats :
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
Modifier :
Compte tenu des commentaires de @philipxy sur les plages de temps nécessitant des vérifications "supérieur ou égal à", j'ai mis à jour le code ici. Je n'ai pas changé le SQLFiddles
.