【问题标题】:Query to check if a given range of date doesn't fits between multiple range of dates查询以检查给定的日期范围是否不适合多个日期范围
【发布时间】:2020-04-07 19:11:13
【问题描述】:

我有一个包含 2 列的表,checkinDate 和 checkoutDate。我要做的是仅在不与其他范围重叠的情况下在表中添加一个范围。我如何知道给定的日期范围是否适合查询的所有这些范围?

例如,从以下行:

startDate   -   endDate
2019-12-10  -   2019-12-15
2019-12-16  -   2019-12-22
2019-12-29  -   2019-01-05
2020-01-20  -   2020-01-25

如果给定的日期范围从 2019-12-232019-12-28,它不会与其他范围重叠,所以我可以添加它在表中。

但如果范围从 2019-12-232019-12-30,它会重叠一个范围,所以我无法将其添加到表格中。

我知道如何逐行检查范围,但不知道如何检查整个表格。

【问题讨论】:

    标签: mysql sql database date date-range


    【解决方案1】:

    这是在插入查询中检查日期重叠的简单方法

    insert into mytable(startDate, endDate)
    select i.startDate, i.endDate
    from (select '2019-12-23' startDate, '2019-12-30' endDate) i
    where not exists (
        select 1 
        from mytable t 
        where t.startDate <= i.endDate and t.endDate >= i.startDate
    )
    

    要插入的日期范围在别名为i 的子查询中声明。如果表中的任何记录与该范围重叠,则跳过插入,否则发生。

    Demo on DB Fiddle

    -- set up
    CREATE TABLE mytable(
       id int auto_increment primary key
       ,startDate DATE  NOT NULL 
      ,endDate   DATE  NOT NULL
    );
    INSERT INTO mytable(startDate,endDate) VALUES ('2019-12-10','2019-12-15');
    INSERT INTO mytable(startDate,endDate) VALUES ('2019-12-16','2019-12-22');
    INSERT INTO mytable(startDate,endDate) VALUES ('2019-12-29','2019-01-05');
    INSERT INTO mytable(startDate,endDate) VALUES ('2020-01-20','2020-01-25');
    
    -- initial table content
    select * from mytable order by startDate
    
    编号 |开始日期 |结束日期 -: | :--------- | :--------- 1 | 2019-12-10 | 2019-12-15 2 | 2019-12-16 | 2019-12-22 3 | 2019-12-29 | 2019-01-05 4 | 2020-01-20 | 2020-01-25
    -- this range does not overlap
    insert into mytable(startDate, endDate)
    select i.startDate, i.endDate
    from (select '2019-12-23' startDate, '2019-12-30' endDate) i
    where not exists (
        select 1 
        from mytable t 
        where t.startDate <= i.endDate and t.endDate >= i.startDate
    )
    
    -- confirm it was inserted
    select * from mytable order by id
    
    编号 |开始日期 |结束日期 -: | :--------- | :--------- 1 | 2019-12-10 | 2019-12-15 2 | 2019-12-16 | 2019-12-22 3 | 2019-12-29 | 2019-01-05 4 | 2020-01-20 | 2020-01-25 5 | 2019-12-23 | 2019-12-30
    -- this range overlaps
    insert into mytable(startDate, endDate)
    select i.startDate, i.endDate
    from (select '2019-12-23' startDate, '2019-12-28' endDate) i
    where not exists (
        select 1 
        from mytable t 
        where t.startDate <= i.endDate and t.endDate >= i.startDate
    )
    
    -- it was not inserted
    select * from mytable order by id
    
    编号 |开始日期 |结束日期 -: | :--------- | :--------- 1 | 2019-12-10 | 2019-12-15 2 | 2019-12-16 | 2019-12-22 3 | 2019-12-29 | 2019-01-05 4 | 2020-01-20 | 2020-01-25 5 | 2019-12-23 | 2019-12-30

    【讨论】:

    • 另一个问题:您知道如何改进查询以确保检查除特定范围之外的所有表范围吗?因为更具体地说,它不是插入查询而是更新,所以我要做的是从表中获取一个范围,用户通过表单更改它,因此我必须检查特定范围是否重叠与表格的所有其他范围,除了采取的范围。
    • 比如拿我上一个问题的同一张表,如果用户想改变范围从2020-01-20 - 2020-01-25 2020-01-20 - 2020-01-30,查询应该允许它,因为初始范围将不再存在。我希望我是清楚的。
    【解决方案2】:

    如果它们重叠,则给定范围的边界中的任何一个都在表中的范围内。因此,您可以使用以下内容:

    SELECT *
           FROM elbat
           WHERE '2019-12-23' > startdate
                 AND '2019-12-23' < enddate
                  OR '2019-12-28' > startdate
                     AND '2019-12-28' < enddate;
    

    【讨论】:

    • 感谢您的回答,但查询没有按我的预期工作(它只逐行检查范围)。 @GMB 的查询正是我要找的。​​span>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    • 1970-01-01
    相关资源
    最近更新 更多