Här är den första delen:Överlappande bilar per användare...
SQLFiddle - korrelerad fråga och gå med i fråga
Andra delen - mer än en användare i en bil samtidigt:SQLFiddle - korrelerad Fråga och gå med Fråga . Fråga nedan...
Jag använder de korrelerade frågorna:
Du kommer sannolikt att behöva index på användar-id och "bil". Men - vänligen kontrollera "förklara planen" för att se hur mysql kommer åt data. Och prova bara :)
Överlappande bilar per användare
Frågan:
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`;
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
Varför fungerar det? eller hur jag tänker kring det:
Jag använder den korrelerade frågan så jag har inga dubbletter att hantera och det är förmodligen det lättaste att förstå för mig. Det finns andra sätt att uttrycka frågan. Var och en har fördelar och nackdelar. Jag vill ha något som jag lätt kan förstå.
Krav:Se till att varje användare inte har två eller flera bilar samtidigt.
Så, för varje användarpost (AllCars) kontrollera hela tabellen (overlapCar) för att se om du kan hitta en annan post som överlappar för tiden för den aktuella posten. Om vi hittar en så välj den aktuella posten som vi kontrollerar (i allCars).
Därför överlappningen kryssrutan är:
-
allCars
userid
ochoverLap
userid
måste vara samma -
allCars
bilrekord ochoverlap
bilrekord måste vara annorlunda -
allCars
tidsintervall ochoverLap
tidsintervallet måste överlappa.Tidsintervallskontrollen:
Använd positiva tester istället för att kontrollera för överlappande tider. Det enklaste tillvägagångssättet är att kontrollera att det inte överlappar och tillämpa en
NOT
till det.
En bil med fler än en användare samtidigt...
Frågan:
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`;
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
Redigera:
Med tanke på kommentarerna från @philipxy , om tidsintervall som kräver "större än eller lika med" kontroller har jag uppdaterat koden här. Jag har inte ändrat SQLFiddles
.