2010-07-23 16 views
70

Considere una columna llamada EmployeeName tabla Employee. El objetivo es eliminar registros repetidos, según el campo EmployeeName.¿Eliminar registros duplicados en SQL Server?

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

Usando una consulta, quiero eliminar los registros que se repiten.

¿Cómo se puede hacer esto con TSQL en SQL Server?

+0

Quieres decir eliminar registros duplicados, ¿verdad? – Sarfraz

+0

puede seleccionar los valores distintos y sus ID relacionados y eliminar aquellos registros cuyos ID no están en la lista ya seleccionada? – DaeMoohn

+1

¿tiene una columna de ID única? –

Respuesta

158

Usted puede hacer esto con las funciones de ventana. Ordenará los duplicados por empire y eliminará todos menos el primero.

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

ejecutarlo como un selecto para ver lo que se elimina:

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

muy inteligente .... –

+2

Si no tiene una clave principal, puede usar 'ORDER BY (SELECT NULL)' http://stackoverflow.com/a/4812038 – Arithmomaniac

7

Usted podría intentar algo como lo siguiente:

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

(esto supone que usted tiene un campo único basado entero)

Personalmente, sin embargo yo diría que eras mejor tratar de corregir el hecho que las entradas duplicadas se están agregando a la base de datos antes de que ocurra, en lugar de como una operación posterior al arreglo.

+0

No tengo el campo único (ID) en mi Mesa. ¿Cómo puedo realizar la operación entonces? – usr021986

27

Suponiendo que su tabla de empleados también tiene una única columna (ID en el ejemplo a continuación), el siguiente trabajo:

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

Esto dejará la versión con el ID más bajo en la tabla.

Editar comentario
de Re McGyver - a partir del SQL 2012

MIN se puede utilizar con numérica, char, varchar, uniqueidentifier, o columnas de fecha y hora, pero no con las columnas bit

Para 2008 R2 y versiones anteriores,

MIN se puede utilizar con numérica, char, varchar o columnas de fecha y hora, pero no con las columnas bit (y también no funciona con el GUID)

Para 2008R2 tendrá que emitir el GUID a un tipo compatible con MIN, por ejemplo

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

SqlFiddle for various types in Sql 2008

SqlFiddle for various types in Sql 2012

+0

Además, en Oracle, podría usar "rowid" si no hay otra columna de identificación única. –

+0

+1 Incluso si no hubiera una columna de ID, se podría agregar una como campo de identidad. –

2
WITH CTE AS 
(
    SELECT EmployeeName, 
      ROW_NUMBER() OVER(PARTITION BY EmployeeName ORDER BY EmployeeName) AS R 
    FROM employee_table 
) 
DELETE CTE WHERE R > 1; 

La magia de las expresiones de tabla comunes.

+0

SubPortal/a_horse_with_no_name - ¿no debería ser esto? seleccionando de una tabla real? Además, ROW_NUMBER debería ser ROW_NUMBER() porque es una función, ¿correcto? – MacGyver

2
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 
1

Trate

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

Si usted está buscando una manera de eliminar duplicados, sin embargo, tiene una clave externa que apunta a la mesa con los duplicados, se puede tomar la siguiente enfoque usando un cursor lento pero efectivo.

Reubicará las claves duplicadas en la tabla de claves externas.

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 [email protected])) 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 
-1

Consulte también la forma de eliminación a continuación.

Declare @Employee table (EmployeeName varchar(10)) 

Insert into @Employee values 
('Anand'),('Anand'),('Anil'),('Dipak'), 
('Anil'),('Dipak'),('Dipak'),('Anil') 

Select * from @Employee 

enter image description here

crea una tabla de ejemplo denominada @Employee y cargado con datos dados.

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

Select * from @Employee 

Resultado:

enter image description here

lo sé, esto se pidió hace seis años, publicando sólo en caso de que es muy útil para cualquier persona.

Cuestiones relacionadas