删除SQL Server中的重复logging?
考虑名为EmployeeName
表Employee
的列。 目标是根据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
结果:
我知道,这是六年前提出的,只是对任何人都有帮助。