你可以使用一個合併而非更新:
merge into address a
using (
select k_id, max(k_add) keep (dense_rank last order by chg_dt) as k_add
from add_hist
group by k_id
) h
on (a.k_id = h.k_id)
when matched then
update set a.k_add = h.k_add
where (a.k_add is null and h.k_add is not null)
or (a.k_add is not null and h.k_add is null)
or a.k_add != h.k_add;
的using
子句中的查詢查找最近的地址從歷史表中的每個ID。當更新的主表上存在匹配的ID時 - 但只有當值不同時,由於where
子句。
隨着一些虛擬的數據:
create table address (k_id number primary key, k_add varchar2(20));
create table add_hist (k_id number, k_add varchar2(20), chg_dt date);
insert into address (k_id, k_add) values (1, 'Address 1');
insert into address (k_id, k_add) values (2, 'Address 2');
insert into address (k_id, k_add) values (3, null);
insert into address (k_id, k_add) values (4, null);
insert into add_hist (k_id, k_add, chg_dt) values (1, 'Address 1', date '2017-01-01');
insert into add_hist (k_id, k_add, chg_dt) values (1, 'Address 2', date '2017-01-02');
insert into add_hist (k_id, k_add, chg_dt) values (1, 'Address 1', date '2017-01-03');
insert into add_hist (k_id, k_add, chg_dt) values (2, 'Address 1', date '2017-01-01');
insert into add_hist (k_id, k_add, chg_dt) values (2, 'Address 2', date '2017-01-02');
insert into add_hist (k_id, k_add, chg_dt) values (2, 'Address 3', date '2017-01-03');
insert into add_hist (k_id, k_add, chg_dt) values (3, 'Address 1', date '2017-01-01');
insert into add_hist (k_id, k_add, chg_dt) values (3, null, date '2017-01-02');
insert into add_hist (k_id, k_add, chg_dt) values (4, 'Address 1', date '2017-01-01');
commit;
運行您的更新語句獲取:
4 rows updated.
select * from address;
K_ID K_ADD
---------- --------------------
1 Address 1
2 Address 3
3
4 Address 1
回滾到起始狀態後,運行合併得到:
2 rows merged.
select * from address;
K_ID K_ADD
---------- --------------------
1 Address 1
2 Address 3
3
4 Address 1
同最終結果,但1行合併而不是2行更新。 (如果在沒有where
子句的情況下運行合併,則所有四行仍然受到影響;如果沒有空檢查,則只更新ID爲2的行)。
我沒有看到一種方式直接讓你在單個更新語句中進行檢查。您必須首先將kad輸出(來自子查詢)保留在變量中,然後只有在該值與表中的值不同時才執行更新。 –
謝謝你Renato :) –
@RenatoAfonso - 爲您的將來Oracle培訓課程:https:// stackoverflow。com/documentation/oracle/8061/update-with-joins#t = 201706230023201170024 – mathguy