Supprimer les duplicates basés sur Group By – SQL

EDIT: Je pense que j'ai maintenant la solution mais j'ai besoin de faire plus de vérification de sens …

DELETE TBLFIRE_TEMP3 FROM TBLFIRE_TEMP3 LEFT OUTER JOIN ( SELECT MIN(FireNo) as FireNo, ActionRef, FRADate, FIREUPRN FROM TBLFIRE_TEMP3 GROUP BY ActionRef, FRADate, FIREUPRN ) as KeepRows ON TBLFIRE_TEMP3.FireNo = KeepRows.FireNo WHERE KeepRows.FireNo IS NULL 

– ############### Commentaires précédents ###############

J'ai une table qui a des duplicates (sur la base de trois colonnes). Je peux les find et les voir en faisant ce qui suit et je voudrais simplement supprimer les duplicates (c'est-à-dire que tous les résultats de count (*) sont '1')

 SELECT COUNT(*),ActionRef, FRADate, FIREUPRN FROM TBLTempTable GROUP BY ActionRef, FRADate, FIREUPRN 

Donc, je peux voir le nombre de fois que ces groupes se produisent. Ce que je veux faire est de supprimer les duplicates. J'ai essayé le ci-dessous mais il supprime chaque ligne, même au singulier:

 DELETE a FROM TblTempTable a JOIN ( SELECT ActionRef, FRADate, FIREUPRN FROM TblTempTable GROUP BY ActionRef, FRADate, FIREUPRN ) d ON (a.ActionRef = b.ActionRef AND a.FRADate = b.FRADate AND a.FIREUPRN = b.FIREUPRN) 

Basé sur les codes que j'ai regardé le guide moi je crois que je suis proche mais actuellement il supprime tout.

Références: SQL- Comment puis-je supprimer les lignes en double? GROUP BY ne supprime pas les duplicates

-Ce sont MySQL donc pas pertinent à la fin:

sélectionner et supprimer des lignes dans des groupes en utilisant mysql Trouver des loggings en double dans MySQL

Une solution simple consiste à utiliser un CTE avec ROW_NUMBER :

 WITH Data AS ( SELECT RN = ROW_NUMBER() OVER (PARTITION BY ActionRef, FRADate, FIREUPRN ORDER BY FRADate ASC), Cnt = COUNT(*) OVER (PARTITION BY ActionRef, FRADate, FIREUPRN), ActionRef, FRADate, FIREUPRN FROM TBLTempTable ) DELETE FROM Data WHERE RN > 1 

Cela supprime tous sauf un, il conserve le FRADate le plus FRADate . Vous devez modifier ORDER BY dans ROW_NUMBER pour modifier cette logique.

Un avantage d'un CTE est que vous pouvez le changer facilement pour voir ce que vous allez supprimer (ou mettre à jour). Par conséquent, il suffit de replace DELETE FROM Data par SELECT * FROM Data .

Il y a aussi une méthode plus simple de lisibilité:

 ;WITH DEDUPE AS ( SELECT ROW_NUMBER() OVER( PARTITION BY ActionRef, FRADate, FIREUPRN ORDER BY (SELECT 1)) AS RN FROM TBLTempTable) DELETE FROM DEDUPE WHERE RN != 1 

Nous utilisons ce script exact au travail quotidiennement. Vous pouvez modifier la clause ORDER BY dans n'importe quelle colonne si vous souhaitez conserver des lignes plus récentes en fonction d'une colonne de date, etc.