对于特定用户 MySQL,查找同一表内的日期范围重叠

2024-05-01

我绝不是 MySQL 专家,所以我正在寻求有关此事的任何帮助。

我需要执行一个简单的测试(原则上),我有这个(简化的)表:

tableid | userid  | car      | From        | To
--------------------------------------------------------
1       | 1       |  Fiesta  |  2015-01-01 | 2015-01-31
2       | 1       |  MX5     |  2015-02-01 | 2015-02-28
3       | 1       |  Navara  |  2015-03-01 | 2015-03-31
4       | 1       |  GTR     |  2015-03-28 | 2015-04-30
5       | 2       |  Focus   |  2015-01-01 | 2015-01-31
6       | 2       |  i5      |  2015-02-01 | 2015-02-28
7       | 2       |  Aygo    |  2015-03-01 | 2015-03-31
8       | 2       |  206     |  2015-03-29 | 2015-04-30
9       | 1       |  Skyline |  2015-04-29 | 2015-05-31
10      | 2       |  Skyline |  2015-04-29 | 2015-05-31

我需要在这里找到两件事:

  1. 如果任何用户的汽车分配的日期重叠超过一天(分配结束可以与新分配开始在同一天)。
  2. 是否有任何两个用户尝试在同一日期分配同一辆车,或者他们在同一辆车上的日期范围重叠。

因此,我正在寻找的查询(或多个查询)应该返回这些行:

tableid | userid  | car      | From        | To
--------------------------------------------------------
3       | 1       |  Navara  |  2015-03-01 | 2015-03-31
4       | 1       |  GTR     |  2015-03-28 | 2015-04-30
7       | 2       |  Aygo    |  2015-03-01 | 2015-03-31
8       | 2       |  206     |  2015-03-29 | 2015-04-30
9       | 1       |  Skyline |  2015-04-29 | 2015-05-31
10      | 2       |  Skyline |  2015-04-29 | 2015-05-31 

我觉得我在这里把头撞在墙上,我很高兴能够在单独的查询中进行这些比较。我需要将它们显示在一张表中,但我总是可以加入结果。

我已经完成了研究和几个小时的测试,但我无法得到我想要的结果。

SQLFiddle 与上述测试数据 http://sqlfiddle.com/#!9/b3fe7/1

顺便说一句,我已经尝试过这些帖子(它们并不完全是我所需要的,但足够接近,或者我是这么认为的):

比较同一个表中的两个日期范围 https://stackoverflow.com/questions/2579844/comparing-two-date-ranges-within-the-same-table

如何比较同一个表中文本列的值 https://stackoverflow.com/questions/25938064/how-to-compare-values-of-text-columns-from-the-same-table

这是我能找到的最接近的解决方案,但是当我在单个表上尝试它(将表连接到自身)时,我得到了疯狂的结果:检查表的时间重叠? https://stackoverflow.com/questions/6571538/checking-a-table-for-time-overlap

EDIT

作为临时解决方案,我采用了不同的方法,类似于我在研究过程中发现的帖子(上面)。我现在将检查新车租赁/分配日期是否与表中的任何日期范围重叠。如果是这样,我将保存日期重叠的行的 ID。这样至少我将能够标记重叠并允许用户查看标记的行并手动解决任何重叠。

感谢所有为此提供帮助的人,我会将 philipxy 答案标记为选定的答案(在接下来的 24 小时内),除非有人有更好的方法来实现这一目标。我毫不怀疑,按照他的回答,我最终将能够达到我需要的结果。但目前我需要采用任何可行的解决方案,因为我需要在接下来的几天内完成我的项目,因此改变了方法。

Edit #2

这两个答案都很棒,对于任何发现这篇文章与我有同样问题的人,请阅读它们并看看小提琴! :) 他们花费了很多惊人的脑力劳动!暂时我不得不采用我在#1编辑中提到的解决方案,但我将调整我的查询以采用@Ryan Vincent方法+@philipxy关于忽略最初一天重叠的编辑/评论。


这是第一部分:每个用户重叠的汽车......

SQLFiddle - 关联查询和连接查询 http://sqlfiddle.com/#!9/af69b/5

第二部分 - 一辆车内同时有多个用户:SQLFiddle - 关联查询和连接查询 http://sqlfiddle.com/#!9/af69b/7。下面查询...

我使用相关查询:

您可能需要用户 ID 和“汽车”的索引。但是 - 请检查“解释计划”以了解 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 中)。

因此overlap检查是:

  • the allCars useridoverLap userid必须相同

  • the allCars汽车记录和overlap行车记录一定是不同的

  • the allCars时间范围和overLap时间范围必须重叠。

    时间范围检查:

    使用阳性测试代替检查重叠时间。最简单的方法是检查它不重叠,然后应用NOT to it.

一辆车同时有多个用户......

查询:

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

Edit:

鉴于 @philipxy 的评论,关于需要“大于或等于”检查的时间范围,我已在此处更新了代码。我没有改变SQLFiddles.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对于特定用户 MySQL,查找同一表内的日期范围重叠 的相关文章

  • 将记录分成两列

    我的数据库中有一个 学生 表 其中包含大约 5 000 条记录 我想将这些记录显示在two分区 如何在不执行查询两次的情况下做到这一点 仅使用单个查询 显示示例http www freeimagehosting net uploads f1
  • 社交应用程序的数据库设计和优化注意事项

    通常的情况 我有一个简单的应用程序 允许人们上传照片并关注其他人 因此 每个用户都会有类似 墙 或 活动源 的东西 他或她可以在其中看到他 她的朋友 他或她关注的人 上传的最新照片 大多数功能都很容易实现 然而 当涉及到这个历史活动源时 由
  • 如何在 phpmyadmin 中创建 MySQL 触发器

    我想在 MySQL 中创建一个触发器 我运行以下命令 mysql gt delimiter mysql gt CREATE TRIGGER before insert money BEFORE INSERT ON money gt FOR
  • 显示表 FULLTEXT 索引列

    我希望运行一个查询 该查询将返回表中全文索引的列列表 该表采用 MyISAM 格式 我将使用 php 来构建查询 理想情况下 我会运行查询 它会返回信息 以便我可以构造一个以逗号分隔的列字符串 例如 名 姓 电子邮箱 这在 MySQL 中可
  • PDO SQLSRV 和 PDO MySQL 在获取 int 或 float 时返回字符串

    当您获取时 PDO MS SQL Server 和 PDO MySQL 都会返回一个字符串数组 即使列的 SQL 类型本应是数字类型 例如 int 或 float 我设法解决了这个问题 但我想了解为什么它们一开始就这样设计 是不是因为PDO
  • 如何在 Laravel 查询中使用多个 OR,AND 条件

    我需要 Laravel 查询帮助 我的自定义查询 返回正确结果 Select FROM events WHERE status 0 AND type public or type private 如何写这个查询Laravel Event w
  • Hibernate 对集合的查询过滤器

    我想执行以下查询 from Item i where i categoryItems catalogId catId 然而 这会产生以下异常 非法尝试取消引用集合 所以我用谷歌搜索 找到了这个 Hibernate 论坛帖子https for
  • MYSQL 区分大小写的 utf8 搜索(使用 hibernate)

    我的登录表具有 utf8 字符集和 utf8 排序规则 当我想要检查用户名并检索该特定用户名的其他信息时 hql 查询会为我提供小写和大写相同的结果 我应该如何处理适用于案例的 HQL 查询 我使用 Mysql 5 和 java hiber
  • 如何正确转义mysql?

    我刚刚发现如果我写 select from tbl where name like foo 然后添加 foo 作为参数及其值 a 用户数据 它不会正确转义 我勒个去 它想要 a 即使我使用参数 我还是忍不住觉得我对 sql 注入持开放态度
  • 如何在列上创建外键,该列的每条记录都可能引用多个表之一中的列?

    我正在创建一个社交网络 它有新闻 照片等多个实体 可以有评论 由于所有评论都具有相同的列并且行为方式相同 唯一的区别是它们的类型 新闻 照片或将来添加的其他内容 我决定为所有评论创建一个表 其中的列名为type 它工作得很好 直到我决定将外
  • MySQL MIN/MAX 所有行

    我有桌子Races与行ID Name and TotalCP 我选择分钟 TotalCP FROM Races 但是我想选择具有最小值的整行 我如何在单个查询中做到这一点 从聚合值获取整行的一般形式是 SELECT FROM Races W
  • 在 MySQL 中使用 COUNT 时如何返回 0 而不是 null

    我使用此查询返回存储在 sTable 中的歌曲列表以及存储在 sTable2 中的总项目数 SQL queries Get data to display sQuery SELECT SQL CALC FOUND ROWS str repl
  • Laravel leftJoin 仅右表的最后一条记录

    我是 Laravel 的新手 我有两张桌子 1 产品 2 价格 products id product int p key name varchar prices id price int p key id product int
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri
  • 将第三个表链接到多对多关联中的桥接表

    设计这个数据库的正确方法是什么 这是我设置表格的方式 我在名为 教师 的表和名为 仪器 的表之间存在多对多关系 然后我有一个连接两者的桥接表 我想将另一个表与 BRIDGE 表关联起来 意思是乐器 老师的组合 该表有 3 行 指定老师可以教
  • 免费 PHP 登录库 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • MySQL连接字符集问题

    我在 Mac 上使用带有 MySQL 的 velosurf 没有任何编码问题 但是当我切换到 Linux 计算机时 从 velosurf 获得的值未正确编码 我发现这可能是默认连接字符集的问题 在 Mac 上我得到 mysql gt sho
  • 在服务器上找不到本地主机或 phpMyAdmin:如何修复?

    我按照安装说明进行操作PHP MySQL and PHPMyAdmin 但是当我尝试访问时http localhost phpmyadmin 我收到此错误 未找到 在此找不到请求的 URL phpmyadmin 服务器 然后我尝试访问loc
  • 比特纳米。重置mysql根密码

    我如何重置 MySQL 中的 root 密码和帐户 因为我按照如何为其他服务器授予权限的说明操作 并且意外地将 root 用户 Mysql 绑定到其他 IP 地址 现在看来我无法在 localhost 上以管理员身份登录 Thanks 您有
  • 如何修改现有表以添加时区

    我有一个包含 500 多个表的大型应用程序 我必须将应用程序转换为时区感知 当前应用程序使用new java util Date GETDATE 与服务器的时区 即没有任何时区支持 我已将这项任务分为几个步骤 以便于开发 我确定的第一个步骤

随机推荐