删除SQL Server中的重复logging?

考虑名为EmployeeNameEmployee的列。 目标是根据EmployeeName字段删除重复的logging。

 EmployeeName ------------ Anand Anand Anil Dipak Anil Dipak Dipak Anil 

使用一个查询,我想删除重复的logging。

SQL Server中如何使用TSQL完成这项工作?

你可以用窗口函数来做到这一点。 它会通过empId命令,删除第一个。

 delete x from ( select *, rn=row_number() over (partition by EmployeeName order by empId) from Employee ) x where rn > 1; 

运行它作为一个select,看看会被删除:

 select * from ( select *, rn=row_number() over (partition by EmployeeName order by empId) from Employee ) x where rn > 1; 

假设您的员工表也有一个唯一的列(下面的例子中的ID ),下面的工作:

 delete from Employee where ID not in ( select min(ID) from Employee group by EmployeeName ); 

这将在表中保留最低ID的版本。

编辑
Re McGyver的评论 – 从SQL 2012开始

MIN可以与数字,char,varchar,uniqueidentifier或datetime列一起使用,但不能与位列一起使用

对于2008 R2及更早版本,

MIN可以与数字,字符,varchar或date时间列一起使用,但不能与位列一起使用(并且它也不适用于GUID)

对于2008R2,您需要将GUID转换为MIN支持的types,例如

 delete from GuidEmployees where CAST(ID AS binary(16)) not in ( select min(CAST(ID AS binary(16))) from GuidEmployees group by EmployeeName ); 

SqlFiddle在Sql 2008中的各种types

在Sql 2012中的各种types的SqlFiddle

你可以尝试如下的东西:

 delete T1 from MyTable T1, MyTable T2 where T1.dupField = T2.dupField and T1.uniqueField > T2.uniqueField 

(这假定你有一个基于整数的唯一字段)

就个人而言,虽然我会说你最好纠正一个事实,那就是在数据库发生重复的条目之前将其添加到数据库中,而不是修复后的操作。

 DELETE FROM MyTable WHERE ID NOT IN ( SELECT MAX(ID) FROM MyTable GROUP BY DuplicateColumn1, DuplicateColumn2, DuplicateColumn3) 

 WITH TempUsers (FirstName, LastName, duplicateRecordCount) AS ( SELECT FirstName, LastName, ROW_NUMBER() OVER (PARTITIONBY FirstName, LastName ORDERBY FirstName) AS duplicateRecordCount FROM dbo.Users ) DELETE FROM TempUsers WHERE duplicateRecordCount > 1 
 WITH CTE AS ( SELECT EmployeeName, ROW_NUMBER() OVER(PARTITION BY EmployeeName ORDER BY EmployeeName) AS R FROM employee_table ) DELETE CTE WHERE R > 1; 

公用表expression式的魔力。

尝试

 DELETE FROM employee WHERE rowid NOT IN (SELECT MAX(rowid) FROM employee GROUP BY EmployeeName); 

如果您正在寻找一种方法来删除重复项,但您有一个外键指向表中重复,您可以采取以下方法使用缓慢而有效的光标。

它将重新定位外键表上的重复键。

 create table #properOlvChangeCodes( id int not null, name nvarchar(max) not null ) DECLARE @name VARCHAR(MAX); DECLARE @id INT; DECLARE @newid INT; DECLARE @oldid INT; DECLARE OLVTRCCursor CURSOR FOR SELECT id, name FROM Sales_OrderLineVersionChangeReasonCode; OPEN OLVTRCCursor; FETCH NEXT FROM OLVTRCCursor INTO @id, @name; WHILE @@FETCH_STATUS = 0 BEGIN -- determine if it should be replaced (is already in temptable with name) if(exists(select * from #properOlvChangeCodes where Name=@name)) begin -- if it is, finds its id Select top 1 @newid = id from Sales_OrderLineVersionChangeReasonCode where Name = @name -- replace terminationreasoncodeid in olv for the new terminationreasoncodeid update Sales_OrderLineVersion set ChangeReasonCodeId = @newid where ChangeReasonCodeId = @id -- delete the record from the terminationreasoncode delete from Sales_OrderLineVersionChangeReasonCode where Id = @id end else begin -- insert into temp table if new insert into #properOlvChangeCodes(Id, name) values(@id, @name) end FETCH NEXT FROM OLVTRCCursor INTO @id, @name; END; CLOSE OLVTRCCursor; DEALLOCATE OLVTRCCursor; drop table #properOlvChangeCodes 

请看下面的删除方法。

 Declare @Employee table (EmployeeName varchar(10)) Insert into @Employee values ('Anand'),('Anand'),('Anil'),('Dipak'), ('Anil'),('Dipak'),('Dipak'),('Anil') Select * from @Employee 

在这里输入图像描述

创build一个名为@Employee的示例表,并用给定的数据加载它。

 Delete aliasName from ( Select *, ROW_NUMBER() over (Partition by EmployeeName order by EmployeeName) as rowNumber From @Employee) aliasName Where rowNumber > 1 Select * from @Employee 

结果:

在这里输入图像描述

我知道,这是六年前提出的,只是对任何人都有帮助。