Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Tìm trùng lặp phạm vi ngày trong cùng một bảng, dành cho người dùng cụ thể MySQL

Đây là phần đầu tiên:Chồng chéo ô tô trên mỗi người dùng ...

SQLFiddle - Truy vấn tương quan và Truy vấn tham gia

Phần thứ hai - nhiều người dùng trên một ô tô cùng lúc: SQLFiddle - Truy vấn và Tham gia tương quan Truy vấn . Truy vấn bên dưới ...

Tôi sử dụng các truy vấn tương quan:

Bạn có thể sẽ cần các chỉ mục trên userid và 'car'. Tuy nhiên - vui lòng kiểm tra 'giải thích kế hoạch' để xem cách mysql đang truy cập dữ liệu. Và chỉ cần thử nó :)

Ô tô chồng chéo trên mỗi người dùng

Truy vấn:

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

Kết quả:

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

Tại sao nó hoạt động? hoặc Tôi nghĩ về nó như thế nào:

Tôi sử dụng truy vấn tương quan để tôi không có các bản sao để xử lý và nó có lẽ là dễ hiểu nhất đối với tôi. Có nhiều cách khác để diễn đạt truy vấn. Mỗi loại đều có ưu điểm và nhược điểm. Tôi muốn một cái gì đó mà tôi có thể dễ dàng hiểu được.

Yêu cầu:Đối với mỗi người dùng, hãy đảm bảo rằng họ không có hai hoặc nhiều ô tô cùng một lúc.

Vì vậy, đối với mỗi bản ghi người dùng (AllCars), hãy kiểm tra bảng hoàn chỉnh (OverCar) để xem liệu bạn có thể tìm thấy một khác bản ghi trùng lặp với thời gian của bản ghi hiện tại. Nếu chúng tôi tìm thấy thì hãy chọn bản ghi hiện tại mà chúng tôi đang kiểm tra (trong allCars).

Do đó, sự trùng lặp kiểm tra là:

  • allCars useridoverLap userid phải giống nhau

  • allCars hồ sơ ô tô và overlap hồ sơ xe phải khác

  • allCars phạm vi thời gian và overLap phạm vi thời gian phải trùng nhau.

    Kiểm tra phạm vi thời gian:

    Thay vì kiểm tra thời gian trùng lặp, hãy sử dụng các bài kiểm tra tích cực. Cách tiếp cận dễ nhất là kiểm tra xem nó không trùng lặp và áp dụng NOT với nó.

Một ô tô có nhiều người dùng cùng lúc ...

Truy vấn:

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

 

Kết quả:

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

Chỉnh sửa:

Theo nhận xét của @philipxy, về khoảng thời gian cần kiểm tra 'lớn hơn hoặc bằng', tôi đã cập nhật mã ở đây. Tôi đã không thay đổi 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. Cách cài đặt MySQL trên CentOS 6

  2. Đếm bao nhiêu hàng được chèn từ truy vấn SQL cuối cùng

  3. Python MySQL - CHỌN hoạt động nhưng không XÓA?

  4. Định dạng dấu thời gian

  5. Ràng buộc mô hình tuyến đường không hoạt động