J'ai besoin de DELETE
lignes dupliquées pour le Sid spécifié sur une MySQL
table.
Comment puis-je faire cela avec une requête SQL?
DELETE (DUPLICATED TITLES) FROM table WHERE SID = "1"
Quelque chose comme ça, mais je ne sais pas comment faire.
mysql
duplicates
Ali Demirci
la source
la source
Réponses:
cela supprime les doublons en place, sans créer de nouvelle table
note: ne fonctionne bien que si l'index tient en mémoire
la source
ALTER IGNORE
.ALTER TABLE foo ENGINE MyISAM
pour contourner le problème, j'ai changé le moteur après.Supposons que vous ayez une table
employee
, avec les colonnes suivantes:Pour supprimer les lignes avec une
first_name
colonne en double :la source
employee
contre elle-même pour une correspondance d'index et une>
vérification sur un index va être lente pour les grandes tables. Ne serait-il pas préférable deSELECT MAX(ID) FROM t GROUP BY unique
et ensuiteJOIN
une correspondance exacte deID
àMAX(ID)
?Ensuite, supprimez les doublons pour tous les SID, pas seulement pour un seul.
Avec table de température
Depuis sa
temp_table
création récente, il n'a pas d'index. Vous devrez les recréer après avoir supprimé les doublons. Vous pouvez vérifier les index que vous avez dans le tableau avecSHOW INDEXES IN table
Sans table de température:
la source
SELECT * FROM table GROUP BY title, SID;
Tout dépend de la façon dont vous savez ce que vous faites.Suppression des lignes en double dans MySQL sur place, procédure pas à pas (en supposant que vous ayez une colonne d'horodatage à trier):
Créez le tableau et insérez quelques lignes:
Supprimez les doublons en place:
Vous avez terminé, les lignes en double sont supprimées, la dernière par horodatage est conservée.
Pour ceux d'entre vous sans horodatage ou colonne unique.
Vous n'avez pas de
timestamp
colonne d'index ou une colonne d'index unique pour trier? Vous vivez dans un état de dégénérescence. Vous devrez effectuer des étapes supplémentaires pour supprimer les lignes en double.créer la table des pingouins et ajouter quelques lignes
faites un clone de la première table et copiez-y.
L'agrégat max fonctionne sur le nouvel index moo:
observer et nettoyer
Que fait cette grosse instruction de suppression SQL?
Les pingouins de table avec l'alias «a» sont laissés joints sur un sous-ensemble de pingouins de table appelé alias «b». La table de droite 'b' qui est un sous-ensemble trouve l'horodatage max [ou max moo] groupé par les colonnes foo et bar. Cela correspond au tableau de gauche «a». (foo, bar, baz) sur la gauche a toutes les lignes du tableau. Le sous-ensemble de droite 'b' a un (maxtimestamp, foo, bar) qui correspond à gauche uniquement sur celui qui EST le max.
Chaque ligne qui n'est pas ce max a pour valeur maxtimestamp NULL. Filtrez vers le bas sur ces lignes NULL et vous avez un ensemble de toutes les lignes regroupées par foo et bar qui ne sont pas le dernier horodatage baz. Supprimez-les.
Faites une sauvegarde de la table avant de l'exécuter.
Empêchez ce problème de se reproduire sur cette table:
Si cela fonctionne, et que cela éteint votre feu de "ligne en double". Génial. Définissez maintenant une nouvelle clé unique composite sur votre table (sur ces deux colonnes) pour éviter que d'autres doublons ne soient ajoutés en premier lieu.
Comme un bon système immunitaire, les mauvaises lignes ne devraient même pas être autorisées à entrer sur la table au moment de l'insertion. Plus tard, tous ces programmes ajoutant des doublons diffuseront leur protestation, et lorsque vous les corrigerez, ce problème ne se reproduira plus.
la source
ID
colonne à incrémentation automatique , laON
clause doit uniquement correspondre à laID
colonne, rien d'autre.Après avoir rencontré ce problème moi-même, sur une énorme base de données, je n'ai pas été complètement impressionné par la performance de l'une des autres réponses. Je souhaite ne conserver que la dernière ligne en double et supprimer le reste.
Dans une instruction à une seule requête, sans table temporaire, cela a fonctionné mieux pour moi,
La seule mise en garde est que je dois exécuter la requête plusieurs fois, mais même avec cela, j'ai trouvé que cela fonctionnait mieux pour moi que les autres options.
la source
Cela semble toujours fonctionner pour moi:
Ce qui conserve l'ID le plus bas sur chacune des dupes et le reste des enregistrements non-dupes.
J'ai également pris les mesures suivantes pour que le problème de dupe ne se produise plus après la suppression:
En d'autres termes, je crée un duplicata de la première table, j'ajoute un index unique sur les champs dont je ne veux pas de duplicata, puis j'en fais un
Insert IGNORE
qui a l'avantage de ne pas échouer comme d'habitude leInsert
ferait la première fois qu'il essaie d'ajouter un enregistrement en double basé sur les deux champs et ignore plutôt ces enregistrements.En se déplaçant vers l'avant, il devient impossible de créer des enregistrements en double basés sur ces deux champs.
la source
ORDER BY
dans leSELECT
pour être sûr de quel disque est réellement passé auNoDupeTable
?ORDER by ID Asc
ne peut pas nuire , donc je vais modifier ma nontheless de réponse.Select Max(ID)
et ensuite,Order by Max(ID)
mais tout ce que cela ferait est d'inverser l'ordre de l'insertion. Pour saisir l'ID le plus élevé, il faudrait, je crois, une jointure de sélection plus complexe car, quelle que soit la façon dont vous commandez ci-dessus, vous récupérerez les valeurs de champ de l'ID inférieur.MAX(ID)
ouMIN(ID)
et au lieu de*
dans leSELECT FROM DupeTable
cependant, sinon vous obtiendrez simplement l'un des noms auID
hasard. En fait, de nombreux SQL et même MySQL strict nécessitent l'appel d'une fonction d'agrégation sur chaque colonne non spécifiée dans laGROUP BY
clause.ID,First,Last,Notes
et des enregistrements1,Bob,Smith,NULL
,2,Bob,Smith,Arrears
puis queSELECT *Max(ID), First,Last,Notes FROM DupeTable group by First,Last
je faisais un , les deux renverraient le même enregistrement, 1, sauf avec un ID différent. Max (ID) reviendrait2,Bob,Smith,NULL
et Min (ID) reviendrait1,Bob,Smith,NULL
. Pour obtenir le deuxième enregistrement avec «Arriérés» dans les notes, il faut une jointure, je crois.Ce qui suit fonctionne pour toutes les tables
la source
Voici une réponse simple:
la source
and a.id_field = b.id
LEFT JOIN
àb
n'a besoin que de comparerb.id
= ena.id_field
supposant qu'ilfield_id
s'agit d'un ID d'incrémentation automatique unique.a.field_being_repeated = b.field_being_repeated
est donc étranger. (b.id_field
n'existe pas non plus dans cette requête, c'estb.id
.Ce travail pour moi de supprimer les anciens enregistrements:
Vous pouvez remplacer min (e.id) par max (e.id) pour supprimer les enregistrements les plus récents.
la source
la source
Je trouve que la solution de Werner ci-dessus est la plus pratique car elle fonctionne quelle que soit la présence d'une clé primaire, ne joue pas avec les tables, utilise un SQL simple à l'épreuve du temps, est très compréhensible.
Comme je l'ai dit dans mon commentaire, cette solution n'a cependant pas été correctement expliquée. C'est donc à moi, basé sur cela.
1) ajouter une nouvelle colonne booléenne
2) ajouter une contrainte sur les colonnes dupliquées ET la nouvelle colonne
3) définissez la colonne booléenne sur true. Cela ne réussira que sur l'une des lignes dupliquées en raison de la nouvelle contrainte
4) supprimer les lignes qui n'ont pas été marquées comme à conserver
5) Déposez la colonne ajoutée
Je vous suggère de conserver la contrainte que vous avez ajoutée, afin d'éviter de nouveaux doublons à l'avenir.
la source
Cette procédure supprimera tous les doublons (y compris les multiples) dans une table, en conservant le dernier duplicata. Ceci est une extension de Récupération du dernier enregistrement dans chaque groupe
J'espère que cela est utile à quelqu'un.
la source
Un autre moyen simple ... en utilisant UPDATE IGNORE:
Vous devez utiliser un index sur une ou plusieurs colonnes (type index). Créez une nouvelle colonne de référence temporaire (ne faisant pas partie de l'index). Dans cette colonne, vous marquez les uniques en la mettant à jour avec la clause ignore. Pas à pas:
Ajoutez une colonne de référence temporaire pour marquer les uniques:
=> cela ajoutera une colonne à votre table.
Mettez à jour la table, essayez de tout marquer comme unique, mais ignorez les erreurs possibles dues à un problème de clé en double (les enregistrements seront ignorés):
=> vous verrez que vos enregistrements en double ne seront pas marqués comme uniques = 'Oui', en d'autres termes, un seul de chaque ensemble d'enregistrements en double sera marqué comme unique.
Supprimez tout ce qui n'est pas unique:
=> Cela supprimera tous les enregistrements en double.
Déposez la colonne ...
la source
unique
colonne DOIT être ajoutée à une contrainte unique avec les colonnes qui sont actuellement dupliquées, sinon tout ne fonctionne pas car SETunique
= 'Yes' n'échouerait jamais.unique
s'agit d'un mot clé mysql. Il doit donc avoir les backticks (comme déjà correctement affichés). Utiliser un autre mot pour la colonne peut être plus pratique.La suppression des doublons sur les tables MySQL est un problème courant, qui vient généralement avec des besoins spécifiques. Au cas où quelqu'un serait intéressé, ici ( Supprimer les lignes en double dans MySQL ) J'explique comment utiliser une table temporaire pour supprimer les doublons de MySQL de manière fiable et rapide, également valable pour gérer les sources de données volumineuses (avec des exemples pour différents cas d'utilisation).
Ali , dans votre cas, vous pouvez exécuter quelque chose comme ceci:
la source
la source
J'adore la réponse de @ eric, mais cela ne semble pas fonctionner si vous avez une très grande table (je reçois
The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay
quand j'essaye de l'exécuter). J'ai donc limité la requête de jointure pour ne considérer que les lignes en double et je me suis retrouvé avec:La clause WHERE dans ce cas permet à MySQL d'ignorer toute ligne qui n'a pas de doublon et ignorera également s'il s'agit de la première instance du doublon, donc seuls les doublons suivants seront ignorés. Remplacez
MIN(baz)
parMAX(baz)
pour conserver la dernière instance au lieu de la première.la source
Cela fonctionne pour les grandes tables:
Pour supprimer la modification la plus ancienne
max(id)
demin(id)
la source
Ceci transformera la colonne
column_name
en clé primaire et ignorera en attendant toutes les erreurs. Ainsi, il supprimera les lignes avec une valeur en double pourcolumn_name
.la source
Je pense que cela fonctionnera essentiellement en copiant la table et en la vidant, puis en n'y remettant que les valeurs distinctes, mais veuillez le vérifier avant de le faire sur de grandes quantités de données.
Crée une copie carbone de votre table
Vide votre table d'origine
Copie toutes les valeurs distinctes de la table copiée dans votre table d'origine
Supprime votre table temporaire.
Vous devez regrouper tous les champs que vous souhaitez conserver distincts.
la source
la source
voici comment j'élimine habituellement les doublons
la source
Vous pouvez simplement utiliser une clause DISTINCT pour sélectionner la liste "nettoyée" (et voici un exemple très simple sur la façon de procéder).
la source
DISTINCT
vous, vous perdez toutes les informations sur les doublons que vous auriez pu avoir en premier lieu. Pouvez-vous montrer un moyen de supprimer les doublons en l'utilisant?Cela pourrait-il fonctionner si vous les comptez, puis ajoutez une limite à votre requête de suppression en n'en laissant qu'une?
Par exemple, si vous en avez deux ou plus, écrivez votre requête comme ceci:
la source
Il n'y a que quelques étapes de base pour supprimer les données en double de votre table:
Voici le tutoriel complet: https://blog.teamsql.io/deleting-duplicate-data-3541485b3473
la source