Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
查找同一表中特定用户MySQL的日期范围重叠_Mysql_Database_Alias_Intervals - Fatal编程技术网

查找同一表中特定用户MySQL的日期范围重叠

查找同一表中特定用户MySQL的日期范围重叠,mysql,database,alias,intervals,Mysql,Database,Alias,Intervals,我绝对不是MySQL专家,所以我正在寻找任何关于这件事的帮助 我需要执行一个简单的测试(原则上),我有这个(简化的)表: 我需要在这里找到两件事: 如果任何用户的车辆分配中存在超过一天的日期重叠(分配的结束日期可以与新分配的开始日期相同) 是否有任何两个用户试图在同一日期获得同一辆车的分配,或者他们在同一辆车上的日期范围重叠 因此,我要查找的查询应返回以下行: tableid | userid | car | From | To --------------------

我绝对不是MySQL专家,所以我正在寻找任何关于这件事的帮助

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

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

  • 如果任何用户的车辆分配中存在超过一天的日期重叠(分配的结束日期可以与新分配的开始日期相同)
  • 是否有任何两个用户试图在同一日期获得同一辆车的分配,或者他们在同一辆车上的日期范围重叠
  • 因此,我要查找的查询应返回以下行:

    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 
    
    我觉得我的头撞到了墙上,我很高兴能够在单独的查询中进行这些比较。我需要将它们显示在一个表中,但我始终可以加入结果

    我已经做了研究和几个小时的测试,但我无法得到任何接近我想要的结果

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

    这是我能找到的最接近的解决方案,但当我在单个表上尝试(将表连接到自身)时,我得到了疯狂的结果:

    编辑

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

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

    编辑#2


    这两个答案都很精彩,如果有人发现这篇文章与我的问题相同,请阅读这两个答案,然后看看小提琴!:)他们做了很多惊人的脑力劳动!暂时我不得不使用我在#1编辑中提到的解决方案,但我将调整我的查询,以使用@Ryan Vincent approach+@philipxy编辑/注释,忽略最初的一天重叠。

    对于每个输入和输出表,找到其意义。即一个由列名参数化的语句模板,也称为谓词,行将其转换为真或假语句,也称为命题。表包含使其谓词成为真命题的行。也就是说,做出正确命题的行放在表中,而做出错误命题的行不在表中。例如,对于您的输入表:

    rental [tableid] was user [userid] renting car [car] from [from] to [to]
    
    然后根据输入表谓词对输出表谓词进行短语化。不要使用类似于1和2的描述:

  • 如果任何用户的车辆分配中存在超过一天的日期重叠(分配的结束日期可以与新分配的开始日期相同)
  • 而是查找任意行在表中表示的谓词:

    rental [tableid] was user [user] renting car [car] from [from] to [to]
        in self-conflict with some other rental
    
    rental [tableid] was user [user] renting car [car] from [from] to [to]
        in conflict with some other user's rental
    
    为了让DBMS计算实现这一点的行,我们必须用给定的谓词加上文本和条件来表示:

    -- query result holds the rows where
    FOR SOME t2.tableid, t2.userid, ...:
        rental [t1.tableid] was user [t1.userid] renting car [t1.car] from [t1.from] to [t1.to]
    AND rental [t2.tableid] was user [t2.userid] renting car [t2.car] from [t2.from] to [t2.to]
    AND [t1.userid] = [t2.userid] -- userids id the same users
    AND [t1.to] > [t2.from] AND ...  -- tos/froms id intervals with overlap more than one day
    ...
    
    -- query result holds the rows where
    FOR SOME t2.*
        rental [t1.tableid] was user [t1.userid] renting car [t1.car] from [t1.from] to [t1.to]
    AND rental [t2.tableid] was user [t2.userid] renting car [t2.car] from [t2.from] to [t2.to]
    AND [t1.userid] <> [t2.userid] -- userids id different users
    AND [t1.car] = [t2.car] -- .cars id the same car
    AND [t1.to] >= [t2.from] AND [t2.to] >= [t1.from] -- tos/froms id intervals with any overlap
    AND [t1.tableid] <> [t2.tableid] -- tableids id different rentals
    
    (在SQL
    SELECT
    语句中,
    JOIN
    ed表的叉积具有
    alias
    形式的列名。将
    视为列名中允许的另一个字符。最后,
    SELECT
    子句删除
    别名

    我们将查询谓词转换为SQL查询,该查询计算使其成为真的行:

    • 表的谓词将替换为表别名
    • 要多次使用同一谓词/表,请生成别名
    • 将谓词中的列
      old
      更改为
      new
      将添加
      old
      =
    • 谓词的
      JOIN
      替换
    • 谓词的
      联合
      替换
    • 谓词的
      替换为
      或适当的
      左连接
    • 条件
    替换,其中
    上的
    条件
  • 对于某些要删除的
    列的谓词true
    ,或者当存在要删除的
    列时,
    选择要保留的不同的
  • 等等(见)
  • (填写省略号):

    根据我们给定的谓词加上文字和条件:

    -- query result holds the rows where
    FOR SOME t2.tableid, t2.userid, ...:
        rental [t1.tableid] was user [t1.userid] renting car [t1.car] from [t1.from] to [t1.to]
    AND rental [t2.tableid] was user [t2.userid] renting car [t2.car] from [t2.from] to [t2.to]
    AND [t1.userid] = [t2.userid] -- userids id the same users
    AND [t1.to] > [t2.from] AND ...  -- tos/froms id intervals with overlap more than one day
    ...
    
    -- query result holds the rows where
    FOR SOME t2.*
        rental [t1.tableid] was user [t1.userid] renting car [t1.car] from [t1.from] to [t1.to]
    AND rental [t2.tableid] was user [t2.userid] renting car [t2.car] from [t2.from] to [t2.to]
    AND [t1.userid] <> [t2.userid] -- userids id different users
    AND [t1.car] = [t2.car] -- .cars id the same car
    AND [t1.to] >= [t2.from] AND [t2.to] >= [t1.from] -- tos/froms id intervals with any overlap
    AND [t1.tableid] <> [t2.tableid] -- tableids id different rentals
    
    --查询结果保存以下行:
    对一些人来说*
    rental[t1.tableid]是用户[t1.userid]将汽车[t1.car]从[t1.from]租到[t1.to]
    出租[t2.tableid]是用户[t2.userid]从[t2.from]到[t2.to]出租汽车[t2.car]
    和[t1.userid][t2.userid]——不同用户的userid
    和[t1.car]=[t2.car]-.cars标识同一辆车
    和[t1.to]>=[t2.from]和[t2.to]>=[t1.from]--tos/froms id间隔有任何重叠
    和[t1.tableid][t2.tableid]——tableid不同的租金
    
    谓词1和谓词2的查询的
    联合
    返回
    谓词1
    谓词2
    所对应的行

    试着学习如何表达谓词——表中的行状态——如果只是作为直观(子)查询的目标

    PS最好始终让数据检查边缘和非边缘情况,以确定条件是否为真。例如,尝试查询1,全球技术法规从31日开始,仅重叠一天,这不应该是自我冲突

    PPS查询发票
    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
    
    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