2017-08-14 4 views
0

J'ai une table dans CockroachDB, j'ai peuplé les données dans la table avant d'appliquer les contraintes pour définir la clé primaire, et parce qu'une partie de l'instruction INSERT a échoué pendant la phase de chargement des données, certains des lignes sont chargées dans la table plus d'une fois par erreur.Comment supprimer des lignes dupliquées dans CockroachDB

La contrainte que je veux appliquer est:

CREATE UNIQUE INDEX ON "MyDB"."MyTable" ("Row_ID"); 

Mais comme les données en double est déjà chargé dans la table, je reçois l'erreur suivante:

pq: multiple primary keys for table "MyTable" are not allowed 

J'ai vérifier si en fait il y a quelques lignes dupliquées avec la requête suivante:

SELECT 
    Row_ID, 
    COUNT(Row_ID) as id 
FROM  
    MyTable 
GROUP BY 
    Row_ID 
HAVING 
    COUNT(Row_ID) > 1; 

Et la requête a montré qu'il y a quelques lignes en double.

Quelle est la meilleure façon de supprimer les lignes en double dans CockroachDB?

Répondre

1

S'il s'agit d'une correspondance exacte, vous pouvez créer une nouvelle table avec les enregistrements distincts.

Ensuite, supprimez toute l'ancienne table et repeusez-la de la table créée à la dernière étape.

Pour créer la table:

create table MyWorkData as select distinct * from MyTable; 

Pour supprimer MyTable

delete from MyTable; 

Pour repeupler MyTable. (Merci @benesch pour la correction de l'instruction)

INSERT INTO MyTable SELECT * FROM MyWorkData 

Enfin, supprimez la table de travail.

+0

Merci, je l'ai essayé, chaque fois que je lance la requête: créer une table MyWorkData en tant que select distinct * de MyTable ;, le processus sera Killed. Je ne sais pas pourquoi, le serveur ne donne aucune autre raison, en utilisant la commande "free -m", je ne pense pas que ce soit à cause de la mémoire. – Cyrus

+0

Vous pouvez également créer la table et la remplir avec un 'select into' en deux étapes. – Juan

+0

@Cyrus, vous pouvez obtenir un rapport d'échec plus détaillé dans les fichiers journaux. S'il vous plaît faites un problème ou venez discuter avec nous sur Gitter! http: // gitter.im/cockroachdb/cockroach – benesch

2

Si vous gardez-vous, courir se soucient pas de qui ligne dupliquée.

DELETE FROM MyTable WHERE rowid IN (
    SELECT MIN(rowid) FROM MyTable GROUP BY Row_ID HAVING COUNT(*) > 1 
); 

Pour tous les doublons, cette requête supprimera tous, mais la ligne qui a été à peu près a créé la première †

Notez que rowid est pas le même que votre colonne Row_ID. rowid est une colonne CockroachDB interne qui est créée par magie pour les tables sans clé primaire, et est garantie d'être unique pour chaque ligne de la table.

rowid stocke les données en fonction du temps d'insertion, mais les lignes insérées presque simultanément par des nœuds avec des horloges asymétriques ne peuvent pas trier dans l'ordre d'insertion.

+0

donc je crois que la recommandation générale sera d'utiliser la sous-requête partout où une jointure est nécessaire avec v1 de cockroachdb? – fortm