Если идентификаторы RecordID в таблице1 являются последовательными, без пробелов, это облегчает нашу первую задачу - нам нужно объединить две строки из таблицы table1, чтобы представить интересующие нас промежутки времени:
Table1 t1a
inner join
Table1 t1b
on
t1a.RecordID = t1b.RecordID - 1
за исключением того, что нам нужно иметь дело с последней строкой, в которой нет другой строки для присоединения, поэтому вместо нее нужно сделать left join
:
Table1 t1a
left join
Table1 t1b
on
t1a.RecordID = t1b.RecordID - 1
Теперь нам нужно выяснить, есть ли в Таблице 2 какие-либо строки, подходящие для этого периода времени. Есть два очевидных способа сделать это - с помощью EXISTS
проверки в предложении where или с помощью дополнительного объединения и фильтрации с использованием DISTINCT
. Какой из них будет работать лучше, зависит от ряда факторов, поэтому стоило бы профилировать оба:
SELECT t1a.RecordID
FROM
Table1 t1a
left join
Table1 t1b
on
t1a.RecordID = t1b.RecordID - 1
where exists(select * from Table2 t2 where t2.DateTime >= t1a.DateTime and (t2.DateTime < t1b.DateTime or t1b.DateTime is null))
или
SELECT DISTINCT t1a.RecordID
FROM
Table1 t1a
left join
Table1 t1b
on
t1a.RecordID = t1b.RecordID - 1
inner join
Table2 t2
on
t2.DateTime >= t1a.DateTime and
(t2.DateTime < t1b.DateTime or t1b.DateTime is null)
Очевидно, что сравнения «больше» и «меньше» могут нуждаться в настройке, в зависимости от включающих или исключающих нижних и верхних границ для временного промежутка, который мы построили.
Если идентификаторы RecordID не являются последовательными, то мы перейдем к поиску правильных строк:
Table1 t1a
left join
Table1 t1b
on
t1a.DateTime < t1b.DateTime
left join
Table1 t1_nogap
on
t1a.DateTime < t1_nogap.DateTime and
t1_nogap.DateTime < t1b.DateTime
Теперь мы обращаемся к Table1 в третий раз (t1_nogap) и пытаемся соединить строку, которая подходит между строками, найденными в t1a и t1b.
Итак, мы добавляем дополнительное условие к предложению where, потому что мы не хотим использовать временные интервалы из t1a и t1b, где мы нашли такую строку:
SELECT DISTINCT t1a.RecordID
FROM
Table1 t1a
left join
Table1 t1b
on
t1a.DateTime < t1b.DateTime
left join
Table1 t1_nogap
on
t1a.DateTime < t1_nogap.DateTime and
t1_nogap.DateTime < t1b.DateTime
inner join
Table2 t2
on
t2.DateTime >= t1a.DateTime and
(t2.DateTime < t1b.DateTime or t1b.DateTime is null)
WHERE
t1_nogap.RecordID is null
(и, очевидно, другой запрос может быть переписан аналогичным образом)