Supprimer les doublons dans une base de données sans l'aide de rowid ou la création d'une table temporaire
Il y a plusieurs années, j'ai été posées lors d'une entrevue téléphonique afin de supprimer les doublons dans une base de données. Après avoir donné plusieurs solutions qui fonctionnent, j'étais finalement dit les restrictions sont les suivantes:
- Supposons que la table a une colonne de type VARCHAR
- Ne peut pas utiliser rowid
- Ne peut pas utiliser des tables temporaires
L'interviewer a refusé de me donner la réponse. J'ai été perplexe depuis.
Après avoir demandé à plusieurs collègues au fil des années, je suis convaincu qu'il n'y a pas de solution. Suis-je tort?!
- Ugh. Faites-moi confiance. Vous ne voulez pas que le travail de toute façon. Une question, où ils font de vous attacher les mains derrière votre dos, comme c'est généralement destiné plus pour montrer comment la puce à l'intervieweur n'est pas de tester les candidats.
- Merci, JohnFx, pour le soutien... ne me rend plus heureux que je n'ai pas poursuivre ce travail.
- La dernière chose que vous voulez est un patron qui ne veut pas d'Une solution, qu'il/elle veut LEUR solution. Ses une recrue gestionnaire d'erreur et très narcissique pour essayer de louer des clones de vous-même.
Vous devez vous connecter pour publier un commentaire.
Et si vous n'avez avoir une réponse, une nouvelle restriction soudain présenter lui-même? Puisque vous parlez de ROWID, je suppose que vous étiez à l'aide d'Oracle. Les solutions sont pour SQL Server.
Inspiré par SQLServerCentral.com http://www.sqlservercentral.com/scripts/T-SQL/62866/
Supprime une ligne à la fois. Lors de la deuxième à la dernière ligne d'un ensemble de doublons disparaît puis le reste de la ligne ne sera pas dans le sous-sélection sur le prochain passage dans la boucle. (GROS Beurk!)
Aussi, voir http://www.sqlservercentral.com/articles/T-SQL/63578/ pour l'inspiration. Il y RBarry Jeune suggère une manière qui pourrait être modifié pour stocker les données dédupliquées dans le même tableau, supprimer tous les rangées d'origine, puis de convertir la stockées les données dédupliquées de retour dans le bon format. Il avait trois colonnes, donc pas exactement analogue à ce que vous faites.
Et puis il pourrait être réalisable avec un curseur. Pas sûr et n'ont pas de temps à le chercher. Mais créer un curseur pour sélectionner tout ce qui sort de la table, dans l'ordre, et ensuite une variable de suivre ce que la dernière ligne ressemblait. Si la ligne courante est la même, de supprimer, d'autre définissez la variable de la ligne actuelle.
C'est complètement Pillée façon de le faire, mais compte tenu de la assanine exigences, voici une solution viable en supposant que SQL 2005 ou plus tard:
Je mettrais un numéro unique de taille fixe dans la colonne de type VARCHAR pour les lignes en double, puis d'analyser le nombre et la suppression de tous, mais le minimum de la ligne. Peut-être que c'est ce que son VARCHAR contrainte est pour. Mais qui pue parce qu'il suppose que votre numéro unique sera adaptée. Boiteux question. Vous ne voulez pas travailler de toute façon. 😉
Suppose que vous êtes la mise en œuvre de la SUPPRESSION de la déclaration pour un moteur SQL. comment allez-vous supprimer les deux lignes d'une table qui sont exactement identiques? Vous avez besoin de quelque chose pour distinguer l'un de l'autre!
Vous avez réellement ne peut pas supprimer totalement les doublons de lignes (TOUTES les colonnes étant égales par ailleurs) sous les contraintes suivantes(fournies)
Il peut toutefois être fait, même si l'une des conditions est détendu. Vous trouverez ici des solutions à l'aide d'au moins une des trois conditions
Supposons que la table est définie comme ci-dessous
Lignes en double identification:
Select col1, col2, col3
à partir de t1
groupe par col1, col2, col3
having count(*) >1
Les doublons de lignes peuvent également être identifiés à l'aide de ceci:
sélectionnez c1,c2,c3, row_number() over (partition by (c1,c2,c3) commande par c1,c2,c3) rn
à partir de t1
REMARQUE: La fonction row_number() analyse de la fonction ne peut pas être utilisé dans une instruction DELETE comme suggéré par JohnFx au moins dans Oracle 10g.
Supprimer à partir de t1 où row_id >
( select min(t1_inner.row_id) à partir de t1 t1_innner
où t1_inner.c1=t1.c1 et t1_inner.c2=t1.c2 et t1_inner.c3=t1.c3))
create table t1_dups comme (
//écriture de la requête ici pour trouver les doublons de lignes dans le liste ci-dessus//
)
supprimer à partir de t1
où t1.c1,t1.c2,t1.c3 in (select * from t1.dup)
insert into t1(
sélectionnez c1,c2,c3 de t1_dups)
Cela permettra d'utiliser une approche similaire pour le cas où nous utilisons une table temp.
Maintenant déposer la table de base .
Renommez le temp de table pour table de base.
De la Mine a été résolu en utilisant cette requête:
supprimer d'où in (select de groupe en ayant count(*) >1)
en PLSQL