Inilah bagian pertama:Mobil yang tumpang tindih per pengguna...
SQLFiddle - Kueri berkorelasi dan Kueri Gabung
Bagian kedua - lebih dari satu pengguna dalam satu mobil secara bersamaan:SQLFiddle - Query dan Gabung yang berkorelasi Permintaan . Kueri di bawah ini...
Saya menggunakan kueri yang berkorelasi:
Anda mungkin memerlukan indeks pada userid dan 'mobil'. Namun - silakan periksa 'jelaskan rencana' untuk melihat bagaimana mysql mengakses data. Dan coba saja :)
Mobil yang tumpang tindih per pengguna
Kueri:
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`;
Hasilnya:
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
Mengapa berhasil? atau Bagaimana menurut saya:
Saya menggunakan kueri yang berkorelasi sehingga saya tidak memiliki duplikat untuk ditangani dan itu mungkin yang paling mudah untuk saya pahami. Ada cara lain untuk mengekspresikan kueri. Masing-masing memiliki kelebihan dan kekurangan. Saya menginginkan sesuatu yang dapat saya pahami dengan mudah.
Persyaratan:Untuk setiap pengguna, pastikan mereka tidak memiliki dua mobil atau lebih pada saat yang bersamaan.
Jadi, untuk setiap catatan pengguna (AllCars) periksa tabel lengkap (overlapCar) untuk melihat apakah Anda dapat menemukan berbeda catatan yang tumpang tindih untuk waktu catatan saat ini. Jika kami menemukannya, pilih catatan saat ini yang sedang kami periksa (di allCars).
Oleh karena itu tumpang tindih cek adalah:
-
allCars
userid
danoverLap
userid
harus sama -
allCars
catatan mobil danoverlap
catatan mobil harus berbeda -
allCars
rentang waktu danoverLap
rentang waktu harus tumpang tindih.Pemeriksaan rentang waktu:
Alih-alih memeriksa waktu yang tumpang tindih, gunakan tes positif. Pendekatan termudah, adalah memeriksanya agar tidak tumpang tindih, dan menerapkan
NOT
untuk itu.
Satu mobil dengan Lebih dari Satu Pengguna secara bersamaan...
Kueri:
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`;
Hasilnya:
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
Sunting:
Mengingat komentar, oleh @philipxy , tentang rentang waktu yang memerlukan pemeriksaan 'lebih besar dari atau sama dengan', saya telah memperbarui kode di sini. Saya belum mengubah SQLFiddles
.