MySQL - 查找时间重叠

时间:2010-04-28 07:02:27

标签: sql mysql database

我在数据库中有2个表,其中包含以下属性:

Booking
=======
booking_id
booking_start
booking_end

resource_booked
===============
booking_id
resource_id

第二个表是“预订”和“资源”之间的关联实体(即,1个预订可以包含许多资源)。属性booking_start和booking_end是包含日期和时间的时间戳。

如果日期/时间与其他类似resource_id的预订重叠或冲突,我可以知道如何找到每个resource_id(resource_booked)吗?

我正在纸上涂抹答案,以图片方式,看看它是否可以帮助我想象我如何解决这个问题,我得到了这个:

  1. 将2个表(Booking,Booked_resource)连接到一个表中,其中包含4个属性。
  2. 按照此处建议的答案:Find overlapping (date/time) rows within one table
  3. 我做了第1步,但第2步让我感到困惑!

    我真的很感激任何帮助!谢谢!

    编辑: 我正在阅读Renshaw先生的回答,并尝试自己做一个,看看我是否理解并得到了这个概念:

    SELECT 
      a.* 
    FROM 
      (SELECT 
        b.creation_date,
        b.booking_id,
        r_b.resource_id,
        b.booking_start,
        b.booking_end 
      FROM Booking b 
      INNER JOIN resource_booked r_b ON b.booking_id = r_b.booking_id) as a,
      (SELECT
        b.booking_id,
        r_b.resource_id,
        b.booking_start,
        b.booking_end 
      FROM Booking b INNER JOIN resource_booked r_b ON b.booking_id = r_b.booking_id) as
    WHERE
      a.resource_id = b.resource_id 
    AND 
      a.booking_id <> b.booking_id 
    AND 
      a.booking_start BETWEEN b.booking_start AND b.booking_end 
    AND
      a.creation_date >= b.creation_date
    

    我试图创建2个相同的表并使用resource_id将它们连接起来,查找具有相似资源ID但不同的booking_id的记录,并查看一个(booking_id)的booking_start日期时间是否在booking_start和另一个(booking_id)的booking_end。

    这真的很乱,我甚至不确定我的询问是否在考虑我的想法但是有些奇迹,我得到了和Renshaw先生一样的答案!

2 个答案:

答案 0 :(得分:1)

编辑:使用其他信息,现在仅限于显示与EARLIER预订相冲突的预订。

我认为这将成功:

SELECT DISTINCT
    b2.booking_id, -- The later booking
    b2.booking_start,
    b2.booking_end,
    b2.creation_date,
    rb1.resource_id, -- The resource over which the two bookings clash
    b1.booking_id, -- The earlier booking
    b1.booking_start,
    b1.booking_end
FROM resource_booked rb1
    INNER JOIN booking b1 ON b1.booking_id = rb1.booking_id
    INNER JOIN booking b2 ON b1.booking_id <> b2.booking_id
        AND b2.booking_start BETWEEN b1.booking_start AND b1.booking_end
    INNER JOIN resource_booked rb2 ON rb2.resource_id = rb1.resource_id
        AND rb2.booking_id = b2.booking_id

这就是它的测试方式:

use tempdb

drop table resource_booked 
drop table Booking

create table Booking
(
    booking_id int,
    booking_start datetime,
    booking_end datetime,
    creation_date datetime
)

create table resource_booked 
(
    booking_id int,
    resource_id int
)

insert Booking values (1, '1 january 2000', '1 march 2000', '1 january 2000')
insert Booking values (2, '1 february 2000', '1 may 2000', '2 january 2000')
insert Booking values (3, '1 april 2000', '1 june 2000', '3 january 2000')
insert Booking values (4, '1 july 2000', '1 august 2000', '4 january 2000')

insert resource_booked values (1, 1)
insert resource_booked values (2, 1)
insert resource_booked values (3, 1)
insert resource_booked values (4, 1)
insert resource_booked values (1, 2)
insert resource_booked values (3, 2)

答案 1 :(得分:0)

哇!我从来没有想过这个...... 我也没想到会有这么详细的帮助,感谢你付出的所有努力!我正在尝试理解并从您的查询中学习:&gt;

预订表有另一个名为creation_date的属性,它显示预订的时间,我希望只显示稍后的预订(时间或冲突重叠)。所以它是:

Booking 1 
=========
creation_date - 2000-01-01 13:00:00
booking_start - 2000-02-24 12:00:00
booking_end   - 2000-02-24 14:00:00

Booking 2 
=========
creation_date - 2000-01-02 15:00:00
booking_start - 2000-02-24 13:00:00
booking_end   - 2000-02-24 15:00:00

预订1和2之间的时间重叠,因为预订2比预订1晚一天,所以只会显示预订2。