小编典典

MySQL-查找时间重叠

sql

我在数据库中有2个表,这些表具有以下属性:

Booking
=======
booking_id
booking_start
booking_end

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

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

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

我以图形方式在纸上涂上答案,以查看它是否可以帮助我形象化如何解决此问题,并得到以下信息:

  1. 将2个表(Booking,Booked_resource)连接到一个具有4个所需属性的表中。
  2. 请按照此处建议的答案:在一个表中查找重叠的(日期/时间)行

我做了第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_id)的booking_start和booking_end之间。

真的很乱,我什至不确定我的查询是否在问我在想什么,但奇迹般地,我得到了与伦肖先生相同的答案!


阅读 198

收藏
2021-03-23

共1个答案

小编典典

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

我认为这可以解决问题:

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)
2021-03-23