Quelle est la meilleure façon de supprimer les lignes en double d'une table SQL Server
assez grande (c'est-à-dire 300 000+ lignes) ?
Bien entendu, les lignes ne seront pas des doublons parfaits en raison de l'existence du champ d'identité RowID
.
MaTable
RowID int not null identity(1,1) primary key,
Col1 varchar(20) not null,
Col2 varchar(2048) not null,
Col3 tinyint not null
En supposant qu'il n'y a pas de nulles, vous GROUPEZ PAR
les colonnes uniques, et SELECTIONNEZ
le MIN (ou MAX)
RowId comme la ligne à conserver. Ensuite, il suffit de supprimer tout ce qui n'a pas d'ID de ligne :
DELETE FROM MyTable
LEFT OUTER JOIN (
SELECT MIN(RowId) as RowId, Col1, Col2, Col3
FROM MyTable
GROUP BY Col1, Col2, Col3
) as KeepRows ON
MyTable.RowId = KeepRows.RowId
WHERE
KeepRows.RowId IS NULL
Dans le cas où vous avez un GUID au lieu d'un entier, vous pouvez remplacer
MIN(RowId)
par
CONVERT(uniqueidentifier, MIN(CONVERT(char(36), MyGuidColumn)))
Il existe un bon article sur la [suppression des doublons][1] sur le site du support Microsoft. Il est assez conservateur - il vous demande de tout faire en plusieurs étapes - mais il devrait bien fonctionner pour les grandes tables.
J'ai utilisé des auto-joints pour faire cela dans le passé, bien que cela puisse probablement être amélioré avec une clause HAVING :
DELETE dupes
FROM MyTable dupes, MyTable fullTable
WHERE dupes.dupField = fullTable.dupField
AND dupes.secondDupField = fullTable.secondDupField
AND dupes.uniqueField > fullTable.uniqueField
Voici un autre bon article sur la [suppression des doublons][1].
Il explique pourquoi c'est difficile : "La base de données SQL est basée sur l'algèbre relationnelle, et les doublons ne peuvent pas se produire dans l'algèbre relationnelle, parce que les doublons ne sont pas autorisés dans un ensemble.
La solution de la table temporaire, et deux exemples mysql.
À l'avenir, allez-vous empêcher cela au niveau de la base de données ou du point de vue de l'application ? Je suggérerais le niveau de la base de données parce que votre base de données devrait être responsable du maintien de l'intégrité référentielle, les développeurs vont juste causer des problèmes ;)
[1] : http://www.xaprb.com/blog/2007/02/06/how-to-delete-duplicate-rows-with-sql-part-2/