106 votes

Suppression des lignes en double dans une base de données sqlite

J'ai une énorme table - 36 millions de lignes - dans SQLite3. Dans cette très grande table, il y a deux colonnes :

  • hash - texte
  • d - réel

Certaines des lignes sont des doublons. C'est-à-dire que les deux hash et d ont les mêmes valeurs. Si deux hachages sont identiques, les valeurs des éléments suivants le sont également d . Cependant, deux personnes identiques d n'implique pas que deux personnes identiques hash 'es.

Je veux supprimer les lignes en double. Je n'ai pas de colonne de clé primaire.

Quel est le moyen le plus rapide de le faire ?

0 votes

Veuillez placer les réponses dans les blocs de réponses. Plus tard, vous pourrez accepter votre propre réponse. Voir aussi Comment fonctionne l'acceptation d'une réponse ?

140voto

Andomar Points 115404

Vous devez trouver un moyen de distinguer les rangs. D'après votre commentaire, vous pourriez utiliser la fonction spéciale colonne rowid pour ça.

Pour supprimer les doublons en conservant le plus petit rowid par (hash,d) :

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

0 votes

SQLite ne vous permet pas d'ajouter une colonne de clé primaire, n'est-ce pas ?

0 votes

sqlite> alter table dist add id integer primary key autoincrement; Error: Cannot add a PRIMARY KEY column

0 votes

Intéressant ! La partie dont vous avez besoin est le autoincrement Mais cela fonctionne-t-il si l'on omet l'option primary key partie ?

5voto

MaDa Points 5571

Je suppose que le plus rapide serait d'utiliser la même base de données pour cela : ajouter une nouvelle table avec les mêmes colonnes, mais avec des contraintes appropriées (un index unique sur la paire hachage/réel ?), itérer à travers la table originale et essayer d'insérer des enregistrements dans la nouvelle table, en ignorant les erreurs de violation de contrainte (c'est-à-dire continuer l'itération lorsque des exceptions sont levées).

Ensuite, supprimez l'ancienne table et renommez la nouvelle en l'ancienne.

1 votes

Ce n'est pas aussi élégant que de simplement modifier la table, je suppose, MAIS l'un des avantages de votre approche est que vous pouvez la réexécuter autant de fois que vous le souhaitez sans toucher/détruire les données sources jusqu'à ce que vous soyez absolument satisfait des résultats.

1voto

rsbarro Points 12575

Si l'ajout d'une clé primaire n'est pas envisageable, une approche consiste à stocker les doublons DISTINCT dans une table temporaire, à supprimer tous les enregistrements en double de la table existante, puis à ajouter les enregistrements dans la table originale à partir de la table temporaire.

Par exemple (écrit pour SQL Server 2008, mais la technique est la même pour toute base de données) :

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

Je ne suis pas sûr que sqlite possède une fonction ROW_NUMBER() mais si c'est le cas, vous pouvez aussi essayer certaines des approches listées ici : Supprimer les enregistrements en double d'une table SQL sans clé primaire

0 votes

+1, je ne suis pas sûr que sqlite supporte la fonction delete <alias> from <table> <alias> mais la syntaxe

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X