mssql里如何保留不重复的记录

怎样把具有相同字段的纪录删除,只留下一条。
例如,表test里有id,name字段
如果有id相同的记录 只留下一条,其余的删除。
id的内容不定,相同的记录数不定。

-----------------------------------------------------------------------------------------------------------------------

--如果要删除test中id列重复值(重复的值只保留最前面的一个)
alter table test add newid int identity(1,1)
go
delete from test where exists(select 1 from test a where a.newid>test.newid and test.id=a.id)
go
alter table test drop column newid
go
--如果要删除更多的列重复,比如id,name两列重复的,只需要在条件后加上一句即可
alter table test add newid int identity(1,1)
go
delete from test where exists(select 1 from test a where a.newid>test.newid and test.id=a.id and test.name=a.name)
go
alter table test drop column newid
go
--依次类推,定义多少列算重复值,就加上相应的条件即可

-----------------------------------------------------------------------------------------------------------------------

--取每条记录都是不重复的做法:
select distinct id,name into #tmp from test --取test表里id,name都不重复的纪录到临时表#tmp里
delete test --清空test里的纪录
insert test(id,name)
select id,name from #tmp --将#tmp里id,name同时唯一的纪录写入test表

-----------------------------------------------------------------------------------------------------------------------

--表里两个及两个以上字段相同,其他字段不同的情况,如表有字段id,name,sex,birtherday,school...,要求删除id,name相同,但其他字段值不同的做法
--exec up_distinct 'test','id','name'
if exists (select * from sysobjects where objectproperty(object_id('test'),'istable')=1)
drop table test
go
create table test(id int,name varchar(20),sex bit,birtherday datetime)
insert into test values(1,'abc',1,'1998-02-02')
insert into test values(1,'abc',0,'1978-02-02')
insert into test values(1,'abc',0,'1988-02-02')
insert into test values(1,'abc',1,'1988-02-02')

--select * from test

if exists (select * from sysobjects where objectproperty(object_id('up_distinct'), 'IsProcedure') = 1)
drop procedure up_distinct
go
create procedure up_distinct(@t_name varchar(30),@f_key varchar(30),@f_name varchar(30))
as
begin
declare @max integer,@id varchar(30) ,@name varchar(30) ,@sql varchar(7999)
select @sql = 'declare cur_rows cursor for select '+@f_key+','+@f_name+' ,count(*) from ' +@t_name +' group by ' +@f_key+','+@f_name +' having count(*) > 1'
exec(@sql)
open cur_rows
fetch cur_rows into @id,@name,@max
while @@fetch_status=0
begin
select @max = @max -1
set rowcount @max
select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+ @id
exec(@sql)
fetch cur_rows into @id,@name,@max
end
close cur_rows
deallocate cur_rows
set rowcount 0
end

--在test约有40万纪录的情况下,游标执行大概要4分钟,distinct的做法需要8秒种。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/68303/viewspace-251510/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/68303/viewspace-251510/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值