7
votes

Supprimer des enregistrements SQL en double pour permettre une clé unique

J'ai une table ('ventes') dans une DB mysql qui devrait avoir à juste titre une contrainte unique appliquée pour empêcher les doublons. Pour d'abord, supprimez les dupes et définir la contrainte se révèle un peu délicate.

Structure de table (simplifiée): p>

  • 'id (unique, autoinc)' li>
  • produit_id li> ul>

    L'objectif est d'appliquer le caractère unique pour le produit_id. La stratégie de désen-duping que je veux postuler consiste à supprimer tous les enregistrements en double, à l'exception du plus récemment créé, par exemple: l'identifiant le plus élevé. P>

    ou pour mettre un autre moyen, je voudrais supprimer uniquement les enregistrements en double, à l'exclusion des ID correspondant par la requête suivante tandis que vous préservant également les enregistrements non dupes existants: P>

    select id 
      from sales s  
    inner join (select product_id, 
                       max(id) as maxId 
                  from sales 
              group by product_id 
                having count(product_id)  > 1) groupedByProdId on s.product_id 
                                                              and s.id = groupedByProdId.maxId
    


0 commentaires

4 Réponses :


12
votes

En réponse à votre commentaire, voici une requête qui fonctionne dans MySQL:

delete <DatabaseName>.yt
from YourTable yt
inner join YourTable yt2
on yt.product_id = yt2.product_id
and yt.id < yt2.id;


1 commentaires

Que faire si i ne peut pas supprimer ou mettre à jour une ligne de parent: une contrainte de clé étrangère échoue («dB». «Une autre carte», la clé étrangère «une autreTable_fk» («Yourtable.product_id») Références 'Yourtable' ('Product_id ') Sur Supprimer aucune action) ?



1
votes

Je pourrai effectuer ce qui suit dans SQL-Server pour éliminer les duplicats: xxx pré>

Il ressemble à l'analogue Supprimer L'instruction pour MySQL pourrait être: p>

DELETE FROM Sales 
USING Sales
    INNER JOIN Sales b ON Sales.product_id = b.product_id AND Sales.id < b.id


1 commentaires

Yah, j'essayais quand vous avez posté votre réponse révisée à la suite de mon commentaire, Andomar. Merci à vous deux.



0
votes

Ce type de problème est plus facile à résoudre avec les CTES et les fonctions de classement, cependant, vous devriez pouvoir faire quelque chose comme ce qui suit pour résoudre votre problème:

Delete Sales
Where Exists(
            Select 1
            From Sales As S2
            Where S2.product_id = Sales.product_id
                And S2.id > Sales.Id
            Having Count(*) > 0
            )


0 commentaires

7
votes

Peut-être utiliser alter Ignore Table ... Ajouter une clé unique . Par exemple: xxx

Voir ceci Post Pythian Pour plus d'informations.

Notez que le ID S est retrouvé dans l'ordre inverse. Je ne pense pas que cette question, puisque l'ordre du ID S ne devrait pas avoir d'importance dans une base de données (autant que je sache!). Si cela vous déplace cependant, le message indiqué ci-dessus montre un moyen de résoudre ce problème aussi. Cependant, il implique de créer une table temporaire qui nécessite plus d'espace disque que la méthode sur place que j'ai postée ci-dessus.


0 commentaires