SQL Server-刪除表中重復數據


在執行語句時難免會輸入相同的數據,這些重復記錄不但沒有用,還可能導致數據庫占用大量資料或導致數據庫查詢索引無效。

如果在建表的時候沒有設置主鍵或unique索引,那么插入完全重復的數據是不會報錯的,結果就是無法修改記錄行或者刪除記錄行。通過SQL語句可以實現刪除表中重復數據。

所有字段均重復的記錄

create table Student (Name char(1),
                      Memo char(2))
go
insert into Student
values(N'A', N'A1'),
      (N'A', N'A1'),
      (N'A', N'A2'),
      (N'B', N'B1'),
      (N'B', N'B1')
-- N'xxx' 標識將單引號中的xxx強制轉換為Unicode編碼的字符,在中文情況下不會出現亂碼
go

方法一

select distinct * into #tmpt from Student
-- 通過distinct取唯一數據存到一個本地臨時表中
drop table Student
select * into Student from #tmpt
-- 把臨時表復制到新的表
drop table #tmpt

方法二

alter table Student
  add Id int identity(1,1)  -- 給表添加標識列
delete from Student
  where Id not in (select min(Id) from Student group by Name)
alter table Student
  drop column Id
select * from Student

  

部分關鍵字段重復的記錄

比如學號字段重復,而其他字段不一定重復。這種屬於隱含錯誤,需要結合實際情況具體分析。

create table t (ID int,
                Name char(1),
                Memo char(2))
go
insert into t
values(1, N'A', N'A1'),
      (2, N'A', N'A2'),
      (3, N'A', N'A3'),
      (4, N'B', N'B1'),
      (5, N'B', N'B2')
go

方法一

delete t from t a
where ID not in (select min(ID) from t where Name = a.Name)
select * from t
go

  

delete from t
where ID not in (select min(ID) from t group by Name)
select * from t
go

  

delete t from t a
where ID <> (select top 1 ID from t where Name = a.Name order by ID)
select * from t
go

  

delete t from t a
where ID > any (select ID from t where Name = a.Name)
select * from t
go

  

方法二

delete t from t a
where exists (select 1 from t where Name = a.Name and ID < a.ID)
select * from t
go

  

delete t from t a
where (select count(*) from t where Name = a.Name and ID < a.ID) > 0
select * from t
go

  

方法三

delete t 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
select * from t
go

  

設立主鍵的表中誤輸入重復記錄

create table Employee (ID int primary key,
                       Name char(20),
                       Age int,
                       Sex bit default 1)
go
insert into Employee
values(1, 'James', 25, default),
      (2, 'James', 25, default),
      (3, 'James', 25, default),
      (4, 'Lisa', 24, 0),
      (5, 'Lisa', 24, 0),
      (6, 'Lisa', 24, 0),
      (7, 'Mirsa', 23, 0),
      (8, 'Mirsa', 23, 0),
      (9, 'Mirsa', 23, 0),
      (10, 'John', 26, default),
      (11, 'Abraham', 28, default),
      (12, 'Lincoln', 30, default)
go

  

delete T from (select row_number() over (partition by Name order by (select 0)) as RowNumber, * from Employee) T
where T.RowNumber > 1
select * from Employee
go

  


免責聲明!

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



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