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 行受影響)
*/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM