更改表内容以匹配查询而不删除所有行

时间:2013-03-12 10:57:14

标签: sql oracle

我有一个表(tblA)和一个查询(queryB)。 queryB的输出与tblA的架构匹配。我想更新tblA,使其内容等于queryB

一个明显的解决方案可能是:

TRUNCATE TABLE tblA

INSERT INTO tblA
(queryB)

但是,我想尽量减少删除和插入的次数。

queryB的结果会有三种情况:

  • 位于queryB,而不是tblA:插入
  • queryBtblA:无所事事
  • 位于tblA,而不是queryB:删除

到目前为止,我发现MS SQL的MERGE支持[NOT] PRESENT IN TARGET/SOURCE,这对于此非常完美 - 但还没有找到Oracle等价物。

有没有一种优雅的方法来实现这一目标?

1 个答案:

答案 0 :(得分:1)

delete from tblA where
  (col1, col2, ...) not in (queryB);

insert into tblA 
  (queryB) minus (select * from tblA);

编辑:
如果将创建小临时表(包含表tblA的<10%的行),则可以计算queryB一次。
假设queryB.col1永远不为空

create table diff as
   select 
      ta.rowid ta_rid, 
      tb.*
   from tblA ta 
      full join (queryB) tb 
         on ta.col1 = tb.col1 
         and ta.col2 = tb.col2 
         and ta.col3 = tb.col3 
   where 
      ta.rowid is null or tb.col1 is null; 

delete from tblA ta 
  where ta.rowid in (select d.ta_rid from diff d where d.ta_rid is not null);
insert into tblA ta 
  select d.col1, d.col2, d.col3 from diff d where d.ta_rid is null;