Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Temukan rentang tanggal yang tumpang tindih dalam tabel yang sama, untuk pengguna tertentu MySQL

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 dan overLap userid harus sama

  • allCars catatan mobil dan overlap catatan mobil harus berbeda

  • allCars rentang waktu dan overLap 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 .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Haruskah saya menonaktifkan mode ketat MySQL?

  2. JIKA TIDAK ADA di pemicu

  3. Mengonversi nilai negatif dari FROM_UNIXTIME

  4. Pemilih pemenang Tiket Lotere PHP

  5. Bagaimana menerapkan tipe data char(N) alih-alih varchar(N) di bidang model Django