sql >> Database teknologi >  >> RDS >> Mysql

Find datointerval overlapninger inden for samme tabel, for specifik bruger MySQL

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 og overLap userid skal være det samme

  • allCars bilrekord og overLap bilrekorden skal være anderledes

  • allCars tidsinterval og overLap 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 .



  1. Hvad er erstatningen for uniqueidentifier i Mysql

  2. SQL Server-markørtyper - Hvad er statiske markører i SQL Server | SQL Server Tutorial / TSQL Tutorial

  3. Hvordan bestemmer jeg den maksimale transaktionsstørrelse i MySQL?

  4. Tvetydig kolonnenavnsfejl på en bestemt server