2016-08-19 29 views
0

如果记录重复,我想删除并留下一条记录。在我的表中,t_id是一个主键,它是int类型和自动增量,id是序列号并且是varchar类型。 起初,我的sql是这样的,但它似乎僵局,并且运行很长时间,似乎永远不会停止。我的两个sql在Oralce中发现重复记录有什么区别?

delete from tbtest 
Where t_id Not In (
select max(t_id) from tbtest having count(id)>1 
group by id 
) 
and id in (
select id from tbtest group by id having count(id)>1 
) 
and create_time<to_timestamp('2016-02-25 11:26:52','yyyy-mm-dd hh24:mi:ss') 

所以我改变它到另一种方式,它运行得非常快?它们之间有什么区别?

delete from tbtest where t_id in (
select t_id from tbtest 
Where t_id Not In (
select max(t_id) from tbtest having count(id)>1 
group by id 
) 
and id in (
select id from tbtest group by id having count(id)>1 
) 
and create_time<=to_timestamp('2016-02-25 11:26:52','yyyy-mm-dd hh24:mi:ss') 
) 
+0

您没有死锁。这需要两个会话。在你的陈述上运行解释计划并发布结果。 – OldProgrammer

+0

那么,你在桌上只有两列吗?如果你有两个以上的列,你确定知道如果序列号“id”是一样的,那么其他的都是一样的?或者你也不关心 - 如果你有相同的id,你只需要为每个序列号“id”保留最高't_id'的行(可能是最近的那一行)? – mathguy

+0

是的,我想要一个记录,如果ID是相同的 – flower

回答

2

这是一个概念验证。试试看看是否有帮助。

create table ta (t_id number primary key, id varchar2(10), val number); 

insert into ta 
    select 1, '1', 33 from dual union all 
    select 2, '2', 44 from dual union all 
    select 3, '2', 55 from dual; 

commit; 

select * from ta; 

     T_ID ID    VAL 
---------- ---------- ---------- 
     1 1     33 
     2 2     44 
     3 2     55 

delete from ta 
where t_id in (select t_id from (select t_id, id, 
     row_number() over (partition by id order by t_id desc) rn from ta) where rn > 1); 

1 row deleted. 

select * from ta; 

     T_ID ID    VAL 
---------- ---------- ---------- 
     1 1     33 
     3 2     55 
+0

我很抱歉,我重新阅读了这个问题,它没有要求解决方案,它询问两个查询之间有什么区别。我发现这些疑问很难遵循,所以我没有尽力回答这个问题。即便如此,我希望这个解决方案可能有所帮助 – mathguy

+0

我用你的例子,这两种方式都可以很好地运行。可能测试数据很少。但是在我自己的数据库中,第一种方式非常慢。 – flower

+1

我想我能够遵循你的第一个查询(需要很长时间的查询)。我不明白你为什么需要按id过滤(只看那些有多行的)。如果t_id不等于该id的最大t_id,那么该id自动必须至少有两行。删除额外的检查(对于ID中的....),看看是否提高了性能。 – mathguy