Her er den første del:Overlappende biler pr. bruger...
SQLFiddle - korreleret forespørgsel og deltagelse i forespørgsel
Anden del - mere end én bruger i én bil på samme tid:SQLFiddle - korreleret forespørgsel og deltagelse Forespørgsel . Forespørgsel nedenfor...
Jeg bruger de korrelerede forespørgsler:
Du skal sandsynligvis bruge indekser på bruger-id og 'bil'. Men - tjek venligst 'forklar planen' for at se, hvordan mysql får adgang til dataene. Og prøv det bare :)
Overlappende biler pr. bruger
Forespørgslen:
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`;
Resultaterne:
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
Hvorfor virker det? eller hvordan jeg tænker over det:
Jeg bruger den korrelerede forespørgsel, så jeg har ikke dubletter at håndtere, og det er nok det nemmeste at forstå for mig. Der er andre måder at udtrykke forespørgslen på. Hver har fordele og ulemper. Jeg vil have noget, jeg nemt kan forstå.
Krav:Sørg for, at hver bruger ikke har to eller flere biler på samme tid.
Så for hver brugerpost (AllCars) skal du kontrollere den komplette tabel (overlapCar) for at se, om du kan finde en anden post, der overlapper for tidspunktet for den aktuelle post. Hvis vi finder en, så vælg den aktuelle post, vi tjekker (i alle biler).
Derfor overlappet check er:
-
allCars
userid
ogoverLap
userid
skal være det samme -
allCars
bilrekord ogoverLap
bilrekorden skal være anderledes -
allCars
tidsinterval ogoverLap
tidsinterval skal overlappe.Tjek af tidsinterval:
Brug positive tests i stedet for at tjekke for overlappende tider. Den nemmeste fremgangsmåde er at kontrollere, at den ikke overlapper, og anvende en
NOT
til det.
Én bil med mere end én bruger på samme tid...
Forespørgslen:
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`;
Resultaterne:
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
Rediger:
I lyset af kommentarerne fra @philipxy om tidsintervaller, der kræver "større end eller lig med"-tjek, har jeg opdateret koden her. Jeg har ikke ændret SQLFiddles
.