SQL删除行不在另一个表中



我正在寻找一个很好的SQL方法(Oracle数据库(来满足下一个要求:

  1. 表A 表A 表>表B。
  2. 中删除行
  3. 两个表都有相同的结构
  4. 某些字段是无效
  5. 列和行的数量很大(比较100k行和20-30列(
  6. 每个行的每个字段都需要从表A 表B。
  7. 进行比较
  8. 这样的要求是由于每天必须运行的过程,因为更改将来自表B

换句话说:表A负表B =>从表A

删除记录
delete from Table A
           where (field1, field2, field3) in
                 (select field1, field2, field3
                    from Table A
                  minus
                  select field1, field2, field3
                    from Table B);

非常重要的是要提及 delete 子句中的正常减去,因为不将无效字段的nulls置于考虑(oracle的未知结果(上,因此没有匹配,那么(。

我也尝试过成功,但是我必须使用nvl函数用虚拟值替换nulls,我不想要它,因为我不能保证在NVL中替换的值不是字段中的有效值。

有人知道一种完成此类事情的方法吗?请记住性能和无效的字段为"必须"。

谢谢

decode找到相同性(即使两个值为null(:

decode( field1, field2, 1, 0 ) = 1  

删除表2中未找到的表1中的行:

delete table1 t
 where t.rowid in (select t1.rowid
                     from table1 t1
                     left outer join table2 t2
                       on decode(t1.field1, t2.field1, 1, 0) = 1
                      and decode(t1.field2, t2.field2, 1, 0) = 1
                      and decode(t1.field3, t2.field3, 1, 0) = 1
                      /* ... */
                      where t2.rowid is null /* no matching row found */
                      ) 

使用现有索引

                      ...
                      left outer join table2 t2
                      on (t1.index_field1=t2.index_field1 or 
                          t1.index_field1 is null and t2.index_field1 is null)
                      and ...

使用左外连接并在您的Where子句中测试null

删除a 来自 左外连接b在a.x = b.x上其中b.x为null

您是否考虑过Oralce SQL MERGE语句?

使用大量记录使用大量操作。明智的性能将更快。

并使用两个表之间的联接以获取要删除的行。可以将无效的列与某些默认值进行比较。

另外,如果您希望表A与表B相似,为什么不截断表A,然后从表B

插入数据

假设您在每个表上可用相同的PK字段...(对此至关重要。(

    create table table_a (id number, name varchar2(25), dob date);
    insert into table_a values (1, 'bob', to_date('01-01-1978','MM-DD-YYYY'));
    insert into table_a values (2, 'steve', null);
    insert into table_a values (3, 'joe', to_date('05-22-1989','MM-DD-YYYY'));
    insert into table_a values (4, null, null);
    insert into table_a values (5, 'susan', to_date('08-08-2005','MM-DD-YYYY'));
    insert into table_a values (6, 'juan', to_date('11-17-2001', 'MM-DD-YYYY'));
    create table table_b (id number, name varchar2(25), dob date);
    insert into table_b values (1, 'bob', to_date('01-01-1978','MM-DD-YYYY'));
    insert into table_b values (2, 'steve',to_date('10-14-1992','MM-DD-YYYY'));
    insert into table_b values (3, null, to_date('05-22-1989','MM-DD-YYYY'));
    insert into table_b values (4, 'mary', to_date('12-08-2012','MM-DD-YYYY'));
    insert into table_b values (5, null, null);
    commit;
    -- confirm minus is working
    select id, name, dob 
    from   table_a
    minus
    select id, name, dob
    from   table_b;
    -- from the minus, re-query to just get the key, then delete by key
    delete table_a where id in (
        select id from (
            select id, name, dob 
            from   table_a
            minus
            select id, name, dob
            from   table_b)
    );
    commit;
    select * from table_a;

但是,如果在某个时间点,将tablea重置为与表格相同的话,为什么不作为另一个答案截断tablea,然后从tableb中选择全部。

100k不是很大。我可以在不到1秒的时间内进行〜100K截断,然后在笔记本电脑实例上插入。

> DELETE FROM purchase WHERE clientcode NOT IN (
>     SELECT clientcode FROM client );

这将删除其客户端代码不在客户端表中的购买表中的行。购买表的客户端代码引用客户端表的客户端代码。

DELETE FROM TABLE1 WHERE FIELD1 NOT IN (SELECT CLIENT1 FROM TABLE2);

最新更新