Mysql
 sql >> база данни >  >> RDS >> Mysql

Намерете припокривания на период от време в рамките на същата таблица за конкретен потребител MySQL

Ето първата част:Припокриващи се автомобили на потребител...

SQLPiddle – корелирана заявка и заявка за присъединяване

Втора част - повече от един потребител в една кола едновременно:SQLPiddle - свързано запитване и присъединяване Запитване . Запитване по-долу...

Използвам свързаните заявки:

Вероятно ще ви трябват индекси на userid и 'car'. Въпреки това - моля, проверете "плана за обяснение", за да видите как mysql осъществява достъп до данните. И просто опитайте :)

Припокриващи се автомобили на потребител

Запитването:

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`;      

Резултатите:

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

Защо работи? или Как мисля за това:

Използвам корелираната заявка, така че нямам дубликати, с които да се справя и вероятно е най-лесният за разбиране за мен. Има и други начини за изразяване на заявката. Всеки има предимства и недостатъци. Искам нещо, което лесно мога да разбера.

Изискване:За всеки потребител се уверете, че няма две или повече коли едновременно.

Така че, за всеки потребителски запис (AllCars) проверете пълната таблица (overlapCar), за да видите дали можете да намерите различен запис, който се припокрива за времето на текущия запис. Ако намерим такъв, изберете текущия запис, който проверяваме (във всички автомобили).

Следователно припокриването проверката е:

  • allCars userid и overLap userid трябва да са еднакви

  • allCars запис на автомобила и overlap записът на автомобила трябва да е различен

  • allCars времеви диапазон и overLap времевият диапазон трябва да се припокрива.

    Проверка на времевия диапазон:

    Вместо да проверявате за припокриващи се времена, използвайте положителни тестове. Най-лесният подход е да проверите дали не се припокрива и да приложите NOT към него.

Една кола с повече от един потребител едновременно...

Запитването:

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`;

 

Резултатите:

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

Редактиране:

С оглед на коментарите от @philipxy относно времеви диапазони, изискващи проверки „по-голямо от или равно на“, актуализирах кода тук. Не съм променил 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. Вземете възрастта на човек в MySQL

  2. Mysql връща неправилен bigint резултат с една, много странна грешка

  3. Хаверсин и Ларавел

  4. MySQL списък на всички процедури

  5. MySQL JOIN връща NULL полета