Во-первых, нам нужен некоторый первичный ключ, чтобы четко определить порядок строк. Нам нужно сравнить предыдущую и следующую строки, и для этого порядок элементарен. Если мы можем использовать job_id, etl_job_run_day, cust_sid
для этого, то вы можете найти проблемные c строки с помощью этого запроса:
select *
from (
select job_id, etl_job_run_day, cust_sid, effective_dt_from edf, effective_dt_to edt, version, latest_fl,
lag(latest_fl) over (partition by job_id order by etl_job_run_day, cust_sid) prev_fl,
lead(latest_fl) over (partition by job_id order by etl_job_run_day, cust_sid) next_fl,
lag(effective_dt_to) over (partition by job_id order by etl_job_run_day, cust_sid) prev_edt,
lead(effective_dt_to) over (partition by job_id order by etl_job_run_day, cust_sid) next_edt,
lead(etl_job_run_day) over (partition by job_id order by etl_job_run_day, cust_sid) next_run
from abc
where latest_fl = 'Y' )
where edt in (prev_edt, next_edt)
Пожалуйста, проверьте его, если все в порядке, вы можете использовать вышеуказанный запрос в качестве исходной таблицы в merge
:
merge into abc a
using (
select *
from (
select job_id, etl_job_run_day, cust_sid, effective_dt_from edf, effective_dt_to edt, version, latest_fl,
lag(latest_fl) over (partition by job_id order by etl_job_run_day, cust_sid) prev_fl,
lead(latest_fl) over (partition by job_id order by etl_job_run_day, cust_sid) next_fl,
lag(effective_dt_to) over (partition by job_id order by etl_job_run_day, cust_sid) prev_edt,
lead(effective_dt_to) over (partition by job_id order by etl_job_run_day, cust_sid) next_edt,
lead(etl_job_run_day) over (partition by job_id order by etl_job_run_day, cust_sid) next_run
from abc
where latest_fl = 'Y' )
where edt in (prev_edt, next_edt)) s
on (a.job_id = s.job_id and a.etl_job_run_day = s.etl_job_run_day and a.cust_sid = s.cust_sid)
when matched then update set
a.latest_fl = case when next_fl = 'Y' then 'N' else a.latest_fl end,
a.effective_dt_to = case when next_fl = 'Y' and next_edt = a.effective_dt_to
then next_run
else a.effective_dt_to end,
a.effective_dt_from = case when prev_fl = 'Y' and prev_edt = a.effective_dt_to
then etl_job_run_day
else a.effective_dt_to end,
version = case when prev_fl = 'Y' then version + 1 else version end
dbfiddle
Это дало мне запрошенные значения для ваших (исправленных) выборочных данных. Опять, пожалуйста, проверьте это. Сделайте копию, если это возможно. Если у вас более двух позиций подряд и там всегда одна и та же версия, вам понадобится дополнительное слияние, но в этом случае следует увеличить все последующие версии? Вы можете сделать это, используя count() over (order by...)
в следующем подобии merge
.