У меня есть таблица истории, которая содержит журнал истории изменений для целевого объекта, и я хочу выбрать строки, значения которых были изменены в течение некоторого периода времени.
Пример данных:
TargetId Value CreatedUtcDateTime
1 1 2018-03-09
1 1 2018-04-09
1 2 2018-04-10
2 3 2018-05-10
2 4 2018-06-10
2 5 2018-07-10
3 4 2017-08-10
3 1 2018-09-12
3 2 2018-10-13
Ожидаемый результат для интервала от '2018-01-01' до '2019-02-01':
TargetId OldValue NewValue CreatedUtcDateTime
1 1 2 2018-04-10
2 3 4 2018-06-10
2 4 5 2018-07-10
3 4 1 2018-09-12
3 1 2 2018-10-13
До сих пор я придумал решение, основанное на функциях Windows:
select c1.TargetId as Coil,
c2.Value as OldValue,
c1.Value as NewValue,
c1.CreatedUtcDateTime as ChangeDate
from (select ROW_NUMBER() over (partition by TargetId order by CreatedUtcDateTime) as rowNum,
TargetId,
Value,
CreatedUtcDateTime from History) c1
join ( select ROW_NUMBER() over (partition by TargetId order by CreatedUtcDateTime) as rowNum,
TargetId,
Value,
CreatedUtcDateTime
from History) c2
on c1.rowNum = c2.rowNum + 1
and c1.TargetId = c2.TargetId
and c1.Value != c2.Value
and c1.CreatedUtcDateTime > c2.CreatedUtcDateTime
where c1.CreatedUtcDateTime > '2018-01-01'
and c1.CreatedUtcDateTime < '2019-02-01'
Но это производит два полных сканирования таблицы, и я хочу избежать этого. Есть ли более эффективный способ добиться этого?