数据库中删除表中重复数据的一点心得

在一个表中有一个自动增长列c1,同时又有两个外健列分别指向另外两个标的主键c2,c3,突然有一天我想让c2与c3组合为一个唯一键,这个时候先必须删除关于c2与c3的重复键(因为c1不可能重复),这就是今天要讨论的话题,如何删除这种情况下的重复键。

在网上查询了一下关于删除重复键的一些做法,很多是用拷贝原表的一个distinct查询表格到临时表,然后删除原表,最后拷贝临时表到原表。近似代码如下:

select distinct * into #temp from table1;

delete table1;

insert into table1 select * from #temp;

drop #temp;

这个方法其实也是一种删除重复行的有效的方法,不过对于缺点就是不能删除部分重复的行,而且如果这个表有触发器的话,可能会引起一些其他的问题(看出发起的代码而定了);如何才能有效地删除重复行呢?

这里我的思路是能找出重复行的主键来,然后条件删除。按照这个思路,我必须先查询出有重复的列,将查询结果导入到临时表#temp:

select c2,c3 into #temp from table group by c2,c3 having count(*) =2;

然后用原表联合查询得到主键信息,为了后面的删除方便,我引用了一个自动增长列再用c2或者c3进行排序,也是这里解决问题的一个关键,将查询结果导入到#temp2;

select identity(int,1,1) as id,a.c2,a.c3 into #temp2 from table1 as a inner join #temp b on a.c1 = b.c1 order by a.c2

此时#temp2表里面就已经保留了全部的重复数据了,但是我们要去除重复行中的一行,可以这么写:

delete #temp2 where id%2=1(奇数行)

或delete #temp2 where id%2=0(偶数行)

此时表#temp2里面保留的仅是重复的数据行了,最后可以删除了:

delete table1 where c1 in (select c1 from #temp2)

大功告成!重复数据已经没有了。

当然这里只是列出的是重复一行的情况,如果重复多行,可以修改count(*)=n;相应的修改delete #temp2的条件子句。

实际上编码中可能要比这复杂的多,我也只是简化了问题的所在而已,大家如果有不同意见的,欢迎指正^_^

转:http://blog.csdn.net/tz_xiong/article/details/1844190

posted @ 2013-12-09 01:46  ygm900  阅读(2240)  评论(0编辑  收藏  举报