SQL处理表重复记录(查询和删除)

SQL处理表重复记录(查询和删除) from CSDN.net
原帖地址:http://topic.csdn.net/u/20080626/00/43d0d10c-28f1-418d-a05b-663880da278a.html

 

-- 处理表重复记录(查询和删除)
/*
*****************************************************************************************************************************************************
1、Num、Name相同的重复值记录,没有大小关系只保留一条
2、Name相同,ID有大小关系时,保留大或小其中一个记录
整理人:中国风(Roy)

日期:2008.06.06
*****************************************************************************************************************************************************
*/

-- 1、用于查询重复处理记录(如果列没有大小关系时2000用生成自增列和临时表处理,SQL2005用row_number函数处理)

-- > --> (Roy)生成測試數據
 
if   not   object_id ( ' Tempdb..#T ' is   null
    
drop   table  #T
Go
Create   table  #T( [ ID ]   int , [ Name ]   nvarchar ( 1 ), [ Memo ]   nvarchar ( 2 ))
Insert  #T
select   1 ,N ' A ' ,N ' A1 '   union   all
select   2 ,N ' A ' ,N ' A2 '   union   all
select   3 ,N ' A ' ,N ' A3 '   union   all
select   4 ,N ' B ' ,N ' B1 '   union   all
select   5 ,N ' B ' ,N ' B2 '
Go


-- I、Name相同ID最小的记录(推荐用1,2,3),方法3在SQl05时,效率高于1、2
方法1:
Select   *   from  #T a  where   not   exists ( select   1   from  #T  where  Name = a.Name  and  ID < a.ID)

方法2:
select  a. *   from  #T a  join  ( select   min (ID)ID,Name  from  #T  group   by  Name) b  on  a.Name = b.Name  and  a.ID = b.ID

方法3:
select   *   from  #T a  where  ID = ( select   min (ID)  from  #T  where  Name = a.Name)

方法4:
select  a. *   from  #T a  join  #T b  on  a.Name = b.Name  and  a.ID >= b.ID  group   by  a.ID,a.Name,a.Memo  having   count ( 1 ) = 1  

方法5:
select   *   from  #T a  group   by  ID,Name,Memo  having  ID = ( select   min (ID) from  #T  where  Name = a.Name)

方法6:
select   *   from  #T a  where  ( select   count ( 1 from  #T  where  Name = a.Name  and  ID < a.ID) = 0

方法7:
select   *   from  #T a  where  ID = ( select   top   1  ID  from  #T  where  Name = a.name  order   by  ID)

方法8:
select   *   from  #T a  where  ID !>all ( select  ID  from  #T  where  Name = a.Name)

方法9(注:ID为唯一时可用):
select   *   from  #T a  where  ID  in ( select   min (ID)  from  #T  group   by  Name)

-- SQL2005:

方法10:
select  ID,Name,Memo  from  ( select   * , min (ID) over (partition  by  Name)  as  MinID  from  #T a)T  where  ID = MinID

方法11:

select  ID,Name,Memo  from  ( select   * ,row_number() over (partition  by  Name  order   by  ID)  as  MinID  from  #T a)T  where  MinID = 1

生成结果:
/*
ID          Name Memo
----------- ---- ----
1           A    A1
4           B    B1

(2 行受影响)
*/


-- II、Name相同ID最大的记录,与min相反:
方法1:
Select   *   from  #T a  where   not   exists ( select   1   from  #T  where  Name = a.Name  and  ID > a.ID)

方法2:
select  a. *   from  #T a  join  ( select   max (ID)ID,Name  from  #T  group   by  Name) b  on  a.Name = b.Name  and  a.ID = b.ID  order   by  ID

方法3:
select   *   from  #T a  where  ID = ( select   max (ID)  from  #T  where  Name = a.Name)  order   by  ID

方法4:
select  a. *   from  #T a  join  #T b  on  a.Name = b.Name  and  a.ID <= b.ID  group   by  a.ID,a.Name,a.Memo  having   count ( 1 ) = 1  

方法5:
select   *   from  #T a  group   by  ID,Name,Memo  having  ID = ( select   max (ID) from  #T  where  Name = a.Name)

方法6:
select   *   from  #T a  where  ( select   count ( 1 from  #T  where  Name = a.Name  and  ID > a.ID) = 0

方法7:
select   *   from  #T a  where  ID = ( select   top   1  ID  from  #T  where  Name = a.name  order   by  ID  desc )

方法8:
select   *   from  #T a  where  ID !<all ( select  ID  from  #T  where  Name = a.Name)

方法9(注:ID为唯一时可用):
select   *   from  #T a  where  ID  in ( select   max (ID)  from  #T  group   by  Name)

-- SQL2005:

方法10:
select  ID,Name,Memo  from  ( select   * , max (ID) over (partition  by  Name)  as  MinID  from  #T a)T  where  ID = MinID

方法11:
select  ID,Name,Memo  from  ( select   * ,row_number() over (partition  by  Name  order   by  ID  desc as  MinID  from  #T a)T  where  MinID = 1

生成结果2:
/*
ID          Name Memo
----------- ---- ----
3           A    A3
5           B    B2

(2 行受影响)
*/



-- 2、删除重复记录有大小关系时,保留大或小其中一个记录


-- > --> (Roy)生成測試數據

if   not   object_id ( ' Tempdb..#T ' is   null
    
drop   table  #T
Go
Create   table  #T( [ ID ]   int , [ Name ]   nvarchar ( 1 ), [ Memo ]   nvarchar ( 2 ))
Insert  #T
select   1 ,N ' A ' ,N ' A1 '   union   all
select   2 ,N ' A ' ,N ' A2 '   union   all
select   3 ,N ' A ' ,N ' A3 '   union   all
select   4 ,N ' B ' ,N ' B1 '   union   all
select   5 ,N ' B ' ,N ' B2 '
Go

-- I、Name相同ID最小的记录(推荐用1,2,3),保留最小一条
方法1:
delete  a  from  #T a  where    exists ( select   1   from  #T  where  Name = a.Name  and  ID < a.ID)

方法2:
delete  a   from  #T a  left   join  ( select   min (ID)ID,Name  from  #T  group   by  Name) b  on  a.Name = b.Name  and  a.ID = b.ID  where  b.Id  is   null

方法3:
delete  a  from  #T a  where  ID  not   in  ( select   min (ID)  from  #T  where  Name = a.Name)

方法4(注:ID为唯一时可用):
delete  a  from  #T a  where  ID  not   in ( select   min (ID) from  #T  group   by  Name)

方法5:
delete  a  from  #T a  where  ( select   count ( 1 from  #T  where  Name = a.Name  and  ID < a.ID) > 0

方法6:
delete  a  from  #T a  where  ID <> ( select   top   1  ID  from  #T  where  Name = a.name  order   by  ID)

方法7:
delete  a  from  #T a  where  ID >any ( select  ID  from  #T  where  Name = a.Name)



select   *   from  #T

生成结果:
/*
ID          Name Memo
----------- ---- ----
1           A    A1
4           B    B1

(2 行受影响)
*/


-- II、Name相同ID保留最大的一条记录:

方法1:
delete  a  from  #T a  where    exists ( select   1   from  #T  where  Name = a.Name  and  ID > a.ID)

方法2:
delete  a   from  #T a  left   join  ( select   max (ID)ID,Name  from  #T  group   by  Name) b  on  a.Name = b.Name  and  a.ID = b.ID  where  b.Id  is   null

方法3:
delete  a  from  #T a  where  ID  not   in  ( select   max (ID)  from  #T  where  Name = a.Name)

方法4(注:ID为唯一时可用):
delete  a  from  #T a  where  ID  not   in ( select   max (ID) from  #T  group   by  Name)

方法5:
delete  a  from  #T a  where  ( select   count ( 1 from  #T  where  Name = a.Name  and  ID > a.ID) > 0

方法6:
delete  a  from  #T a  where  ID <> ( select   top   1  ID  from  #T  where  Name = a.name  order   by  ID  desc )

方法7:
delete  a  from  #T a  where  ID <any ( select  ID  from  #T  where  Name = a.Name)


select   *   from  #T
/*
ID          Name Memo
----------- ---- ----
3           A    A3
5           B    B2

(2 行受影响)
*/





-- 3、删除重复记录没有大小关系时,处理重复值


-- > --> (Roy)生成測試數據
 
if   not   object_id ( ' Tempdb..#T ' is   null
    
drop   table  #T
Go
Create   table  #T( [ Num ]   int , [ Name ]   nvarchar ( 1 ))
Insert  #T
select   1 ,N ' A '   union   all
select   1 ,N ' A '   union   all
select   1 ,N ' A '   union   all
select   2 ,N ' B '   union   all
select   2 ,N ' B '
Go

方法1:
if   object_id ( ' Tempdb..# ' is   not   null
    
drop   table  #
Select   distinct   *   into  #  from  #T -- 排除重复记录结果集生成临时表#

truncate   table  #T -- 清空表

insert  #T  select   *   from  #     -- 把临时表#插入到表#T中

-- 查看结果
select   *   from  #T

/*
Num         Name
----------- ----
1           A
2           B

(2 行受影响)
*/

-- 重新执行测试数据后用方法2
方法2:

alter   table  #T  add  ID  int   identity -- 新增标识列
go
delete  a  from   #T a  where    exists ( select   1   from  #T  where  Num = a.Num  and  Name = a.Name  and  ID > a.ID) -- 只保留一条记录
go
alter   table  #T  drop   column  ID -- 删除标识列

-- 查看结果
select   *   from  #T

/*
Num         Name
----------- ----
1           A
2           B

(2 行受影响)

*/

-- 重新执行测试数据后用方法3
方法3:
declare  Roy_Cursor  cursor  local  for
select   count ( 1 ) - 1 ,Num,Name  from  #T  group   by  Num,Name  having   count ( 1 ) > 1
declare   @con   int , @Num   int , @Name   nvarchar ( 1 )
open  Roy_Cursor
fetch   next   from  Roy_Cursor  into   @con , @Num , @Name
while   @@Fetch_status = 0
begin  
    
set   rowcount   @con ;
    
delete  #T  where  Num = @Num   and  Name = @Name
    
set   rowcount   0 ;
    
fetch   next   from  Roy_Cursor  into   @con , @Num , @Name
end
close  Roy_Cursor
deallocate  Roy_Cursor

-- 查看结果
select   *   from  #T
/*
Num         Name
----------- ----
1           A
2           B

(2 行受影响)
*/

你可能感兴趣的:(sql)