sql语句去除重复记录(多表连接的查询)

--处理表重复记录(查询和删除)
/******************************************************************************************************************************************************
1、Num、 Name 相同的重复值记录,没有大小关系只保留一条
2、 Name 相同,ID有大小关系时,保留大或小其中一个记录
******************************************************************************************************************************************************/
 
--1、用于查询重复处理记录(如果列没有大小关系时2000用生成自增列和临时表处理,SQL2005用row_number函数处理)
 
--> --> 生成測試數據
  
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  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  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、删除重复记录有大小关系时,保留大或小其中一个记录
 
 
--> --> 生成測試數據
 
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  from  #T a  where   exists( select  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  from  #T a  where  ID  not  in  ( select  min (ID)  from  #T  where  Name =a. Name )
 
方法4(注:ID为唯一时可用):
delete  from  #T a  where  ID  not  in ( select  min (ID) from  #T  group  by  Name )
 
方法5:
delete  from  #T a  where  ( select  count (1)  from  #T  where  Name =a. Name  and  ID<a.ID)>0
 
方法6:
delete  from  #T a  where  ID<>( select  top  1 ID  from  #T  where  Name =a. name  order  by  ID)
 
方法7:
delete  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  from  #T a  where   exists( select  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  from  #T a  where  ID  not  in  ( select  max (ID)  from  #T  where  Name =a. Name )
 
方法4(注:ID为唯一时可用):
delete  from  #T a  where  ID  not  in ( select  max (ID) from  #T  group  by  Name )
 
方法5:
delete  from  #T a  where  ( select  count (1)  from  #T  where  Name =a. Name  and  ID>a.ID)>0
 
方法6:
delete  from  #T a  where  ID<>( select  top  1 ID  from  #T  where  Name =a. name  order  by  ID  desc )
 
方法7:
delete  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、删除重复记录没有大小关系时,处理重复值
 
 
--> --> 生成測試數據
  
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  from   #T a  where   exists( select  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语句)