Вот ответ, который выбирает записи в вашем ожидаемом наборе результатов из тестовых данных на основе предоставленного вами образца.Я выражаю это так непристойно просто потому, что ваш вопрос не полностью отражает требуемые бизнес-правила, так что это немного догадка:
select t1.VAR_GRP,
t1.VAR_FLD ,
t1.VAR_FLD_VAL,
min(case when t1.VAR_FLD_VAL != t2.VAR_FLD_VAL then t1.LST_UPDT_TS
else t2.min_LST_UPDT_TS end) as LST_UPDT_TS
from table1 t1
join ( select VAR_GRP,
VAR_FLD ,
VAR_FLD_VAL,
min(LST_UPDT_TS) over (partition by VAR_GRP, VAR_FLD, VAR_FLD_VAL) min_LST_UPDT_TS,
row_number() over (partition by VAR_GRP, VAR_FLD, VAR_FLD_VAL order by HIST_TS desc) rn
from table2
) t2 on t1.VAR_GRP = t2.VAR_GRP
and t1.VAR_FLD = t2.VAR_FLD
where t2.rn = 1
and (t2.min_LST_UPDT_TS >= to_date('2018-06-10 11:00:00', 'yyyy-mm-dd hh24:mi:ss') - (1/24) or t1.VAR_FLD_VAL != t2.VAR_FLD_VAL)
group by t1.VAR_GRP,
t1.VAR_FLD ,
t1.VAR_FLD_VAL
/
Итак, бизнес-правила, которые я реализовал, были:
- вычисляет минимум для LST_UPDT_TS для записей в
table2
- , если минимум для LST_UPDT_TS находится в течение последних двух часов
- или значение в
table1
не совпадаетзначение в table2
- затем включите в набор результатов
Здесь - демонстрационная версия LiveSQL (требуется бесплатная учетная запись Oracle - извините, но SQL Fiddle был довольно ненадежнымпоздно) .
Обратите внимание, что это решение не работает, если изменения вставляют запись для новой (VAR_GRP,VAR_FLD)
в table1
или УДАЛЯЮТ запись из table1
.Я не уверен, как вы будете представлять эти действия в table2
.
В интересах других Искателей, в комментарии я описал реализацию журналирования как "чокнутый".Почему так резко?Поскольку процесс генерирует много ненужной работы и теряет важную информацию в сделке:
- Процесс ведения журнала делает снимок всех существующих записей в VAR_GRP, которому принадлежит запись, которая изменилась.Было бы меньше труда заполнить
table2
только старой версией измененной записи. - Процесс обновляет (или, по-видимому, удаляет и повторно вставляет) все значения LST_UPDT_TS в
table1
всехсуществующие записи в VAR_GRP, которому принадлежит измененная запись.Было бы меньше труда просто обновить отметку времени измененной записи. - Поскольку процесс делает снимок всех записей
table1
, невозможно увидеть, какая запись была изменена в table2
без выполнениямного работы. - Поскольку процесс обновляет все записи в
table1
, невозможно увидеть, когда каждая запись фактически изменилась, не обратившись к table2
.
Журналирование (аудит АКА, history) - это издержки, потому что они запускаются всякий раз, когда мы выполняем DML для наших таблиц.Поэтому считается хорошей практикой минимизировать влияние на базу данных;эта реализация делает прямо противоположное.Он также отбрасывает самую важную информацию - , запись которой была изменена - и требует, чтобы мы делали это из других записей.Плохое представление.
Лучшей реализацией было бы вставить старую версию только что измененной записи table1
в table2
и пометить измененную запись table1
отметкой времени.