2010-04-28 120 views
6

我在数据库中具有2代表具有以下属性:的MySQL - 寻找时间重叠

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个表(预订,Booked_resource)到一个表与所需的4个属性。
  2. 按照建议的答案在这里:Find overlapping (date/time) rows within one table

我做了第一步,但第二步是让我百思不得其解!

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

编辑: 我读伦肖先生的答案,并试图做一个对我自己,看看我的理解,我得到了这个概念:

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加入它们,查找具有相似资源标识但booking_id不同的记录,并查看其中一个(booking_id)的booking_start datetime是否位于另一个(booking_id)的booking_start和booking_end之间。

这真的很混乱,我甚至不确定我的问题是否在问我脑海里有什么奇迹,但是我得到了和Renshaw先生一样的答案!

回答

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) 
+0

出于某种原因,我收到了某些记录的“重复项目”: * b2.booking_id | B2。creation_date | rb1.resource_id | b1.creation_date | b1.booking_id * ** 23 | 2006-08-31 13:21:25.0 | 12 | 2006-09-05 14:12:17.0 | 21 ** 另外一行如下: ** 21 | 2006-09-05 14:12:17.0 | 12 | 2006-08-31 13:21:25.0 | 23 ** – Cuppy 2010-04-28 09:16:43

+0

我添加了另一个WHERE子句,用于检查b1.creation_date> = b2.creation_date,以便只有稍后做出的预订才会显示,并且它似乎有效!再次感谢! – Cuppy 2010-04-28 09:29:13

0

哇!我从未想过这件事.. 我没有想到会有这么详细的帮助,谢谢你为此付出的一切努力!我试图从您的查询中了解和学习:>

预订表中还有另一个属性,称为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将显示做了一天后,预订时间重叠。

+0

谢谢!我尝试格式化该区域时遇到问题! :> – Cuppy 2010-04-28 07:52:35

+0

最好是通过编辑将其他信息添加到您的原始问题中。可以使用与queston关联的评论功能进行讨论 – 2010-04-28 07:55:22

+0

我已经编辑了我的答案以考虑到这些额外信息 – 2010-04-28 07:59:28