tutorial manager sql database sqlite sqlite3

manager - Eliminar filas duplicadas de la base de datos sqlite



sqlite windows (3)

Tengo una gran tabla, 36 millones de filas, en SQLite3.

En esta mesa muy grande, hay dos columnas

  • hash - texto
  • d - real

Sin embargo, algunas de las filas son duplicados. Es decir, tanto hash como d tienen los mismos valores.

Además, si dos hash son idénticos, también lo son los valores de d, pero dos ds idénticos no implican dos hashes idénticos

De todos modos, quiero eliminar las filas duplicadas. No tengo una columna de clave principal. ¿Cuál es la forma más rápida de hacer esto?

EDITAR: delete from dist where rowid not in (select max(rowid) from dist group by hash);

Parece hacer el truco.


Necesitas una forma de distinguir las filas. Según su comentario, podría usar la columna especial rowid para eso.

Para eliminar duplicados, manteniendo el rowid más rowid por (hash,d) :

delete from YourTable where rowid not in ( select min(rowid) from YourTable group by hash , d )


Si agregar una clave principal no es una opción, entonces un enfoque sería almacenar los duplicados DISTINCT en una tabla temporal, eliminar todos los registros duplicados de la tabla existente y luego volver a agregar los registros a la tabla original desde la tabla temporal .

Por ejemplo (escrito para SQL Server 2008, pero la técnica es la misma para cualquier base de datos):

DECLARE @original AS TABLE([hash] varchar(20), [d] float) INSERT INTO @original VALUES(''A'', 1) INSERT INTO @original VALUES(''A'', 2) INSERT INTO @original VALUES(''A'', 1) INSERT INTO @original VALUES(''B'', 1) INSERT INTO @original VALUES(''C'', 1) INSERT INTO @original VALUES(''C'', 1) DECLARE @temp AS TABLE([hash] varchar(20), [d] float) INSERT INTO @temp SELECT [hash], [d] FROM @original GROUP BY [hash], [d] HAVING COUNT(*) > 1 DELETE O FROM @original O JOIN @temp T ON T.[hash] = O.[hash] AND T.[d] = O.[d] INSERT INTO @original SELECT [hash], [d] FROM @temp SELECT * FROM @original

No estoy seguro de si sqlite tiene una función de tipo ROW_NUMBER() , pero si lo hace, también podría probar algunos de los enfoques enumerados aquí: Eliminar registros duplicados de una tabla SQL sin una clave principal


Supongo que lo más rápido sería usar la misma base de datos: agregar una nueva tabla con las mismas columnas, pero con las restricciones adecuadas (¿un índice único en hash / par real?), Recorrer la tabla original e intentar insertar registros en la nueva tabla, ignorando los errores de violación de restricciones (es decir, continúa iterando cuando se producen excepciones).

A continuación, elimine la tabla anterior y cambie el nombre de la nueva a la anterior.