Hier is het eerste deel:Overlappende auto's per gebruiker...
SQLFiddle - gecorreleerde Query en Join Query
Tweede deel - meer dan één gebruiker tegelijk in één auto:SQLFiddle - gecorreleerde Query en Join Zoekopdracht . Vraag hieronder...
Ik gebruik de gecorreleerde zoekopdrachten:
U zult waarschijnlijk indexen nodig hebben op userid en 'car'. Controleer echter het 'plan uitleggen' om te zien hoe mysql toegang heeft tot de gegevens. En probeer het gewoon :)
Overlappende auto's per gebruiker
De vraag:
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`;
De resultaten:
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
Waarom werkt het? of Hoe ik erover denk:
Ik gebruik de gecorreleerde query, zodat ik geen duplicaten heb om mee om te gaan en het is waarschijnlijk het gemakkelijkst te begrijpen voor mij. Er zijn andere manieren om de vraag uit te drukken. Elk heeft voor- en nadelen. Ik wil iets dat ik gemakkelijk kan begrijpen.
Vereiste:Zorg ervoor dat elke gebruiker niet twee of meer auto's tegelijk heeft.
Controleer dus voor elk gebruikersrecord (AllCars) de volledige tabel (overlapCar) om te zien of u een andere kunt vinden record dat overlapt voor de tijd van het huidige record. Als we er een vinden, selecteer dan het huidige record dat we controleren (in allCars).
Daarom is de overlap controle is:
-
de
allCars
userid
en deoverLap
userid
moet hetzelfde zijn -
de
allCars
autorecord en deoverLap
autorecord moet anders zijn -
de
allCars
tijdbereik en deoverLap
tijdbereik moet overlappen.De tijdbereikcontrole:
Gebruik positieve tests in plaats van te controleren op overlappende tijden. De eenvoudigste benadering is om te controleren of het niet overlapt, en een
NOT
. toe te passen ernaartoe.
Eén auto met meer dan één gebruiker tegelijk...
De vraag:
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`;
De resultaten:
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
Bewerken:
Met het oog op de opmerkingen van @philipxy over tijdbereiken waarvoor controles 'groter dan of gelijk aan' nodig zijn, heb ik de code hier bijgewerkt. Ik heb de SQLFiddles
niet veranderd .