繁体   English   中英

从另一个表中删除不匹配的行

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM