2012-03-12 51 views
1

我有一个表(在MS Access中)在每个记录中存储开始和结束与项目关联的一个事件的日期。多个事件可能与每个项目相关联,并且事件时间段可能重叠。需要一个SQL查询来列出所有具有在一段时间内开始但在时间段结束时没有活动事件的项目

我将使用术语“开放事件”来表示开始日期少于结束日期并且结束日期大于给定日期的事件。

我想要一个查询,该查询给出了在给定时间段内至少有一个打开事件但在时间段结束时还有打开事件的项目列表。理想情况下,我还想列出这些项目中每个项目在该时间段内最后一次开放活动的ID。

这里是一些事件记录的列表,代表我需要覆盖的一些案例。有问题的时间是2012-03-20至2012-03-30:

eventId itemId startDate endDate 
e1  i1  2012-03-21 2012-03-23 -- event open entirely inside of time period 
e2  i2  2012-03-19 2012-03-21 -- event open at start date 
e3  i3  2012-03-29 2012-03-31 -- event open at end date 

e4  i4  2012-03-19 2012-03-26 -- multi-event item with event open at end date 
e5  i4  2012-03-22 2012-03-25 
e6  i4  2012-03-29 2012-03-31 
e7  i4  2012-04-01 2012-04-30 

e8  i5  2012-03-19 2012-03-25 -- multi-event item with no events open at end date 
e9  i5  2012-03-22 2012-03-29 
e10  i5  2012-03-25 2012-03-26 
e11  i5  2012-04-01 2012-04-30 

e12  i6  2012-03-13 2012-03-19 -- event not in time period at all 

这里是我想看到的是这样的结果的项目(和他们最后的公开活动)查询:

i1, e1 
i2, e2 
i5, e9 -- note that e9.endDate > e8.endDate and e10.endDate, and that e11 falls after the time period in question, so is not considered the last event for the item 

回答

1

你可以left join到列出了在结束日期打开所有事件的子查询。如果您要求子查询中的列为空,则排除与子查询匹配的所有事件/项目组合。

select distinct e.eventId 
,  e.itemId 
from Events e 
left join 
     (
     select distinct itemId 
     from Events 
     where startDate < '2012-03-30' -- Started before end 
       and '2012-03-30' < EndDate -- Closed after end 
     ) oe 
on  e.itemId = oe.itemId 
where e.startDate < '2012-03-30' -- Started before end 
     and '2012-03-20' < e.EndDate -- Ended after start 
     and oe.eventId is null -- Not open at end 
+0

这是非常接近的,并且类似于迄今为止我已经能够提出的最佳解决方案,但由于结果集包括i4,但它不应该。我只想在结束时打开** no **事件。 – ralbatross 2012-03-12 18:21:21

+0

啊,但如果做出以下更改,我认为它做我需要的:在子查询'选择不同的itemId'而不是'选择不同的eventId,itemId',并只加入itemId而不是itemId和eventId。 @Andomar,如果您在这些更改中进行编辑,我会将其标记为解决方案。 – ralbatross 2012-03-12 18:40:05

+0

在答案中编辑。 – Andomar 2012-03-12 18:44:33

相关问题