2010-10-12 56 views
5

Estoy seguro de que esto se ha preguntado antes, pero me estaba costando encontrarlo.Eliminar varias filas duplicadas en la tabla

Tengo múltiples grupos de duplicados en una tabla (3 registros para uno, 2 para otro, etc.) - múltiples filas donde hay más de 1.

A continuación se muestra lo que se me ocurrió para eliminarlos, pero tengo que ejecutar el script para muchos duplicados sin embargo existen:

set rowcount 1 
delete from Table 
where code in (
    select code from Table 
    group by code 
    having (count(code) > 1) 
) 
set rowcount 0 

Esto funciona bien hasta cierto punto. Necesito ejecutar esto para cada grupo de duplicados, y luego solo borro 1 (que es todo lo que necesito en este momento).

¡Agradezco tu ayuda/comentario!

+0

¿Cuál de los duplicados desea conservar: el primero/más bajo, o el último/máximo? ¿Y para qué versión de SQL Server? –

+0

O bien, la ID máxima funcionaría. SQL Server 2000 (sí, lo sé) – Dan

+2

posible duplicado de [SQL - ¿Cómo puedo eliminar filas duplicadas?] (Http://stackoverflow.com/questions/18932/sql-how-can-i-remove-duplicate-rows) –

Respuesta

6

Si tiene una columna clave en la tabla, puede usarla para identificar de manera única las filas "distintas" en su tabla.

Solo use una sub consulta para identificar una lista de ID para filas únicas y luego elimine todo lo que esté fuera de este conjunto. Algo a lo largo de las líneas de .....

create table #TempTable 
(
    ID int identity(1,1) not null primary key, 
    SomeData varchar(100) not null 
) 

insert into #TempTable(SomeData) values('someData1') 
insert into #TempTable(SomeData) values('someData1') 
insert into #TempTable(SomeData) values('someData2') 
insert into #TempTable(SomeData) values('someData2') 
insert into #TempTable(SomeData) values('someData2') 
insert into #TempTable(SomeData) values('someData3') 
insert into #TempTable(SomeData) values('someData4') 

select * from #TempTable 

--Records to be deleted 
SELECT ID 
FROM #TempTable 
WHERE ID NOT IN 
(
    select MAX(ID) 
    from #TempTable 
    group by SomeData 
) 

--Delete them 
DELETE 
FROM #TempTable 
WHERE ID NOT IN 
(
    select MAX(ID) 
    from #TempTable 
    group by SomeData 
) 

--Final Result Set 
select * from #TempTable 

drop table #TempTable; 

Como alternativa puede usar un CET por ejemplo:

WITH UniqueRecords AS 
(
    select MAX(ID) AS ID 
    from #TempTable 
    group by SomeData 
) 
DELETE A 
FROM #TempTable A 
    LEFT outer join UniqueRecords B on 
     A.ID = B.ID 
WHERE B.ID IS NULL 
+0

Acabo de notar que el OP está en SQL Server 2000 de todos modos, pero es posible hacerlo de manera más eficiente con un CTE como aquí http://stackoverflow.com/questions/18932/sql-how-can-i-remove-duplicate-rows/3822833 # 3822833 –

0
SET ROWCOUNT 1  
DELETE Table  
FROM Table a  
WHERE (SELECT COUNT(*) FROM Table b WHERE b.Code = a.Code) > 1  
WHILE @@rowcount > 0  
    DELETE Table  
    FROM Table a  
    WHERE (SELECT COUNT(*) FROM Table b WHERE b.Code = a.Code) > 1  
SET ROWCOUNT 0 

Esto eliminará todas las filas duplicadas, pero se puede añadir atributos si quiero comparar de acuerdo a ellos

+2

"BORRAR tabla DESDE la tabla" ??? ¿Has ejecutado este script? –

2

Con frecuencia es más eficiente copiar filas únicas en la tabla temporal,
soltar la tabla fuente, cambiar el nombre de la tabla temporal hacia atrás.

que reutiliza la definición y datos de #temptable, denominado aquí como SrcTable lugar, ya que es imposible cambiar el nombre de la tabla temporal en una normal)

create table SrcTable 
(
    ID int identity(1,1) not null primary key, 
    SomeData varchar(100) not null 
) 

insert into SrcTable(SomeData) values('someData1') 
insert into SrcTable(SomeData) values('someData1') 
insert into SrcTable(SomeData) values('someData2') 
insert into SrcTable(SomeData) values('someData2') 
insert into SrcTable(SomeData) values('someData2') 
insert into SrcTable(SomeData) values('someData3') 
insert into SrcTable(SomeData) values('someData4') 

por John Sansom en previous answer

-- cloning "unique" part 
SELECT * INTO TempTable 
FROM SrcTable --original table 
WHERE id IN 
(SELECT MAX(id) AS ID 
FROM SrcTable 
GROUP BY SomeData); 
GO; 

DROP TABLE SrcTable 
GO; 

sys.sp_rename 'TempTable', 'SrcTable' 
+0

si usa esta estrategia, después de renombrar debe leer claves, restricciones, valores de identidad, índices y relaciones – pomarc

1

alternativa, puede utilizar la función ROW_NUMBER() para filtrar los duplicados

;WITH [CTE_DUPLICATES] AS 
(
SELECT RN = ROW_NUMBER() OVER (PARTITION BY SomeData ORDER BY SomeData) 
FROM #TempTable 
) 
DELETE FROM [CTE_DUPLICATES] WHERE RN > 1 
+0

El OP para esta pregunta es sobre SQL Server 2000. –

Cuestiones relacionadas