您的位置:首页 > 其它

删除未设置主键的表里的重复记录

2009-06-13 20:45 246 查看
以前建的表,因为别的原因,未设置主键,现在翻看一下,惨不忍睹,重复记录占了一半,决定设置主键,因此首先得将重复记录删除。这么多记录不可能手工去删,得写个脚本来完成工作。

源表如下:





里面有重复记录,打算用item_number作为表的主键。item_number后面的数据不同的话,任意留一个即可。

首先需要把不重复的主键字段选择出来,这个不难。之后,根据选择出来的不重复字段删除另外的重复字段,比如现在可以选出item_number有1,2,3,4,5五个值,然后就需要分别选择item_number为1的记录,只留一条,其余的全部删除。sql2005里面有个delete top语法,用起来比较爽,但是现在时sql2000环境,所以不能用了。

这里我有两个思路:

一,增加一个标识字段,用后删除。

根据item_number单一值选择一行记录,select top 1,在标识字段里进行标记,如此类推,将其他的值的记录的一行进行标记,之后删除所有未被标记的记录。

二,根据item_number单一值选择一行记录,select top 1,与上面不同的是将这些记录都放到一个临时表里,然后删除源表里的所有记录,最后将临时表里的数据复制后源表。

然后考虑一下性能问题:第一个思路需要更改源表结构,第二个思路会使用一个临时表。如果记录不多,采用第二个思路比较方便,但是如果要操作的表数据庞大,显然需要采用第一个思路。

下面我用第二个思路写得存储过程

create proc test_sql_variant
as
declare @sql_variant sql_variant--用这个作为主键列值的变量
declare @rowcount int--后面循环的计数器
--建两个表,第一个暂时储存非重复数据,第二个暂时存储主键列值
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[temSurTbl]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[temSurTbl]
CREATE TABLE [dbo].[temSurTbl] ([item_number] [int] NULL ,[item_quality] [int] NULL ) ON [PRIMARY]
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[temtab_pk]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[temtab_pk]
--得到将作为主键的列的非重复查询
select distinct(item_number) into temtab_pk from tbl1
set @rowcount=@@rowcount
--关键就在这个循环了,思路里写清楚了,这里就不谈了
while @rowcount>0
begin
select top 1 @sql_variant=item_number from temtab_pk
delete from temtab_pk where item_number=@sql_variant
insert into temSurTbl select top 1 *  from tbl1 where item_number=@sql_variant
set @rowcount=@rowcount-1
end
delete from tbl1
insert into tbl1 select *  from temSurTbl

该存储过程测试通过。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: