2009-03-25 5 views
4

J'ai une table qui a des lignes uniques à l'exception d'une valeur dans une colonne (appelons-la 'Name'). Une autre colonne est "Date" qui est la date à laquelle elle a été ajoutée à la base de données. Ce que je veux faire est de trouver les valeurs dupliquées dans 'Name', puis supprimer celles avec les dates les plus anciennes dans 'Date', en laissant la plus récente.Comment puis-je trouver des entrées en double et supprimer les plus anciennes en SQL?

Cela ressemble à une requête relativement facile, mais je connais très peu de choses sur SQL à part de simples requêtes.

Des idées?

+0

Quelle version de SQL Server utilisez-vous? – Sung

+0

SQL Server 2005 Express –

+0

@The KZA: Merci. J'attendais si je peux utiliser "Dense_rank" ou non. "dense_rank" rend ce type de requête plus facile – Sung

Répondre

5

Trouver les doublons et supprimer plus ancien

alt text

Voici le code

create table #Product (
    ID  int identity(1, 1) primary key, 
    Name  varchar(800), 
    DateAdded datetime default getdate() 
) 

insert #Product(Name) select 'Chocolate' 
insert #Product(Name,DateAdded) select 'Candy', GETDATE() + 1 
insert #Product(Name,DateAdded) select 'Chocolate', GETDATE() + 5 
select * from #Product 

;with Ranked as (
    select ID, 
     dense_rank() 
     over (partition by Name order by DateAdded desc) as DupeCount 
    from #Product P 
) 
delete R 
from Ranked R 
where R.DupeCount > 1 

select * from #Product 
+0

Cela semble très bien, merci beaucoup, beaucoup, mais il des erreurs en disant l'instruction DELETE en conflit avec la contrainte de référence dans une autre table, qui je suppose ouvre un autre ensemble de problèmes pour moi. Je peux cependant manuellement cliquer et supprimer les lignes manuellement? –

+0

Si la ligne que vous supprimez est référencée à partir d'une autre table, supprimez d'abord la ligne de cette table; en utilisant l'ID extrait du CTE "Classé" dans mon exemple ci-dessus. – Sung

5

supprimer de la table où a1 existe (select * de la table où a2 = a2.name a1.name et a2.date> a1.date)

+0

En cours d'exécution cela me donne "Syntaxe incorrecte près de 'a1'." Est-ce que a1 est un espace réservé pour autre chose? Désolé, c'est une question stupide :) –

+0

Le problème est probablement que "table" dans la requête devrait vraiment être le nom de la table contenant les colonnes Name et Date, pas littéralement le mot "table", ce qui n'est pas autorisé dans ce contexte parce que c'est un mot-clé SQL. – yukondude

+0

Ce que j'ai compris :) Pourtant, je reçois toujours cette erreur de syntaxe –

0

Vous pourriez probablement y parvenir avec une auto-jointure et EST NON NULLE.

Il peut être un peu dangereux de se joindre à des requêtes DELETE, car plus il est complexe, plus le risque de suppression est important dans certaines circonstances.

Mais je voudrais l'aborder comme. La jointure et l'option IS NOT NULL recherchent toutes les lignes pour lesquelles il existe une nouvelle ligne portant le même nom. Il gère également le cas de deux lignes avec la même date correctement - si elles ont la même date, alors il passe par rowid (quel qu'il soit).

Espérons que quelque chose comme ça fonctionne.

Questions connexes