Я предполагаю, что каждый раздел может содержать только один Create или CreateSystem, в противном случае ваши требования плохо определены.Следующее не проверено, так как у меня нет ни образца таблицы, ни образца данных в легко используемом формате:
;With Partitions as (
Select
t1.FK1,
t1.FK2,
t1.CreationTS as StartTS,
t2.CreationTS as EndTS
From
Table t1
left join
Table t2
on
t1.FK1 = t2.FK1 and
t1.FK2 = t2.FK2 and
t1.CreationTS < t2.CreationTS and
t2.ActionCode in ('Create','CreateSystem')
left join
Table t3
on
t1.FK1 = t3.FK1 and
t1.FK2 = t3.FK2 and
t1.CreationTS < t3.CreationTS and
t3.CreationTS < t2.CreationTS and
t3.ActionCode in ('Create','CreateSystem')
where
t1.ActionCode in ('Create','CreateSystem') and
t3.FK1 is null
), PartitionRows as (
SELECT
t1.FK1,
t1.FK2,
t1.ActionCode,
t2.SomeAttributeValue,
ROW_NUMBER() OVER (PARTITION_FRAGMENT_ID BY t1.FK1,T1.FK2,t1.StartTS ORDER BY t2.CreationTS desc) as rn
from
Partitions t1
inner join
Table t2
on
t1.FK1 = t2.FK1 and
t1.FK2 = t2.FK2 and
t1.StartTS <= t2.CreationTS and
(t2.CreationTS < t1.EndTS or t1.EndTS is null)
)
select * from PartitionRows where rn = 1
(Обратите внимание, что здесь я использую все виды зарезервированных имен)
Основная логика: Разделы CTE используются для определения каждого раздела в терминах FK1, FK2, включающей временной отметки начала и исключительной конечной отметки времени.Это делается путем тройного соединения с базовой таблицей.строки из t2
выбираются так, чтобы они встречались после строк из t1
, затем строки из t3
выбираются так, чтобы они находились между совпадающими строками из t1
и t2
.Затем в предложении WHERE мы исключаем все строки из результирующего набора, в котором было найдено совпадение из t3
- в результате строка из t1
и строка из t2
представляют начало двух смежных разделов.
Затем второй CTE извлекает все строки из Table
для каждого раздела, но присваивает оценку ROW_NUMBER()
в каждом разделе на основе отсортированного по убыванию значения CreationTS
, в результате чего ROW_NUMBER()
1 в пределахкаждый раздел является последней строкой.
Наконец, в пределах выбора мы выбираем те строки, которые встречаются последними в их соответствующих разделах.
Все это предполагает, что значения CreationTS
различныв каждом разделе.Возможно, я смогу переработать его и с помощью PK, если это предположение не подтвердится.