第一个答案 - 但请参阅下面的最后一个答案,其中包含 OP 添加的附加约束。
-- 如果你想在最近的 endTime 之后获得下一个 startTime 并避免重叠,你想要类似的东西:
select
distinct
e1.deviceId,
e1.EventEnd,
e3.EventStart
from Events e1
join Events e3 on e1.eventEnd < e3.eventStart /* Finds the next start Time */
and e3.eventStart = (select min(eventStart) from Events e5
where e5.eventStart > e1.eventEnd)
and not exists (select * /* Eliminates an e1 rows if it is overlapped */
from Events e5
where e5.eventStart < e1.eventEnd
and e5.eventEnd > e1.eventEnd)
对于您的三行的情况:
INSERT INTO Events VALUES (1, '01/01/2012 08:00', '01/01/2012 10:00')
INSERT INTO Events VALUES (2, '01/01/2012 18:00', '01/01/2012 20:00')
insert into Events values (2, '01/01/2012 09:00', '01/01/2012 11:00')
这给出了 1 个结果:
January, 01 2012 11:00:00-0800 January, 01 2012 18:00:00-0800
但是,我假设您可能也想在 DeviceId 上进行匹配。在这种情况下,在连接上,您将添加e1.DeviceId = e3.DeviceId
和e1.deviceId = e5.deviceId
SQL小提琴在这里: http ://sqlfiddle.com/#!3/3899c/8
--
好的,最后的编辑。这是一个查询,添加了 deviceIds 并添加了 distinct 以说明同时结束的事件:
SELECT distinct
e1.DeviceID,
e1.EventEnd as LastEndTime,
e3.EventStart as NextStartTime
FROM Events e1
join Events e3 on e1.eventEnd < e3.eventStart
and e3.deviceId = e1.deviceId
and e3.eventStart = (select min(eventStart) from Events e5
where e5.eventStart > e1.eventEnd
and e5.deviceId = e3.deviceId)
where not exists (select * from Events e7
where e7.eventStart < e1.eventEnd
and e7.eventEnd > e1.eventEnd
and e7.deviceId = e1.deviceId)
order by e1.deviceId, e1.eventEnd
与 e3 的连接找到了下一个开始。加入 e5 保证这是当前结束时间之后的最早开始时间。如果考虑的行的结束时间与不同的行重叠,则与 e7 的连接会消除一行。
对于此数据:
INSERT INTO Events VALUES (1, '01/01/2012 08:00', '01/01/2012 10:00')
INSERT INTO Events VALUES (2, '01/01/2012 18:00', '01/01/2012 20:00')
insert into Events values (2, '01/01/2012 09:00', '01/01/2012 11:00')
insert into Events values (2, '01/02/2012 11:00', '01/02/2012 15:00')
insert into Events values (1, '01/02/2012 10:00', '01/02/2012 12:00')
insert into Events values (2, '01/02/2012 10:00', '01/02/2012 15:00')
insert into Events values (2, '01/03/2012 09:00', '01/03/2012 10:00')
你得到这个结果:
1 January, 01 2012 10:00:00-0800 January, 02 2012 10:00:00-0800
2 January, 01 2012 11:00:00-0800 January, 01 2012 18:00:00-0800
2 January, 01 2012 20:00:00-0800 January, 02 2012 10:00:00-0800
2 January, 02 2012 15:00:00-0800 January, 03 2012 09:00:00-0800
SQL 小提琴在这里: http ://sqlfiddle.com/#!3/db0fa/3