[英]Delete rows which is not match from another table
Src
**************************
EMPID ENTERTAINMENT
**************************
101 BaseBall,Cricket
102 Badminton,Chess
103 Golf,Reading Books
************************************
使用delimiter ,
分割记录并将其添加到目标表中。
gt
**************************
EMP_ID ENTERTAINMENT
**************************
101 BaseBall
101 Cricket
102 Badminton
102 Chess
103 Golf
103 Reading Books
**********************************
删除从源表到目标表不匹配的行。 即,如果源表中发生任何更改,则也需要在目标表中复制相同的内容。
预期方案示例:
Src
**************************
EMPID ENTERTAINMENT
**************************
101 BaseBall
102 Badminton
103 Golf,Reading Books
************************************
gt
**************************
EMP_ID ENTERTAINMENT
**************************
101 BaseBall
102 Badminton
103 Golf
103 Reading Books
**********************************
我已经从target(Tgt)表中删除了101即(101-板球)和102即(102 -Chess),因为源表(Src)表中没有可用数据。 谁能建议,如何使用SQL查询实现?
首先,SRC的测试数据:
create table src(empid, ENTERTAINMENT) as
select 101, 'BaseBall,Cricket' from dual union all
select 102, 'Badminton,Chess' from dual union all
select 103, 'Golf,Reading Books' from dual;
现在创建一个与TGT应该对应的视图:
create or replace view v_tgt as
select empid, x.entertainment
from src, xmltable(
'if (contains($X,",")) then ora:tokenize($X,",") else $X'
passing entertainment as X
columns entertainment varchar2(64) path '.'
) x;
这是拆分字符串的许多方法之一。 有关其他一些信息,请参见https://stewashton.wordpress.com/category/splitting-strings/ 。
现在,从视图创建TGT表:
create table tgt as select * from v_tgt;
最后,这是一条MERGE语句,它将TGT与V_TGT进行比较,并使TGT相同:
merge /*+ qb_name(SYNC_PARTITION) USE_NL(O) */ into (
select /*+ qb_name(target) */
"EMPID", "ENTERTAINMENT", rowid Z##RID
from TGT
) O
using (
select /*+ qb_name(CDC_PARTITION) */ * from (
select /*+ qb_name(before_filter) */
"EMPID", "ENTERTAINMENT",
case
when Z##NEW = 1
and sum(Z##NEW) over(partition by
"EMPID", "ENTERTAINMENT"
order by null rows unbounded preceding) > sum(Z##OLD) over(partition by
"EMPID", "ENTERTAINMENT"
)
then 'I'
when Z##OLD = 1
and sum(Z##OLD) over(partition by
"EMPID", "ENTERTAINMENT"
order by null rows unbounded preceding) > sum(Z##NEW) over(partition by
"EMPID", "ENTERTAINMENT"
)
then 'D'
end Z##OP, Z##RID
FROM (
select /*+ qb_name(old) */
"EMPID", "ENTERTAINMENT",
1 Z##OLD, 0 Z##NEW, rowid Z##RID
from TGT O
union all
select /*+ qb_name(new) */
"EMPID", "ENTERTAINMENT",
0, 1, null
from v_tgt N
)
)
where Z##OP is not null
) N
on (
O.Z##RID = n.Z##RID
)
when matched then update set
"EMPID"=N."EMPID"
delete where N.Z##OP = 'D'
when not matched then insert (
"EMPID", "ENTERTAINMENT"
) values(
N."EMPID", N."ENTERTAINMENT"
);
我使用在这里提供的工具生成了此MERGE语句: https : //stewashton.wordpress.com/2018/02/12/comp_sync-1-a-new-table-compare-sync-package/
最好的问候,炖阿什顿
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.