2010-07-27 4 views
7

dire que j'ai des lignes en double dans ma table et bien ma conception de base de données est de 3ème classe: -Comment supprimer complètement les lignes en double

Insert Into tblProduct (ProductId,ProductName,Description,Category) Values (1,'Cinthol','cosmetic soap','soap'); 
Insert Into tblProduct (ProductId,ProductName,Description,Category) Values (1,'Cinthol','cosmetic soap','soap'); 
Insert Into tblProduct (ProductId,ProductName,Description,Category) Values (1,'Cinthol','cosmetic soap','soap'); 
Insert Into tblProduct (ProductId,ProductName,Description,Category) Values (1,'Lux','cosmetic soap','soap'); 
Insert Into tblProduct (ProductId,ProductName,Description,Category) Values (1,'Crowning Glory','cosmetic soap','soap'); 
Insert Into tblProduct (ProductId,ProductName,Description,Category) Values (2,'Cinthol','nice soap','soap'); 
Insert Into tblProduct (ProductId,ProductName,Description,Category) Values (3,'Lux','nice soap','soap'); 
Insert Into tblProduct (ProductId,ProductName,Description,Category) Values (3,'Lux','nice soap','soap'); 

Je veux seulement 1 instance de chaque rangée doit être présent dans ma table. Ainsi, 2nd, 3rd and last row qui sont complètement identiques doivent être supprimés. Quelle requête puis-je écrire pour cela? Peut-il être fait sans créer de tables temporaires? Juste dans une seule requête?

Merci à l'avance :)

+0

Le premier enregistrement basé sur l'ordre d'insertion? Pour quelle version de SQL Server? –

+0

Sql Server 2008. – TCM

+0

Je vais deviner que vous voulez dire 3ème forme normale quand vous dites 3e classe. Si elle permet des doublons complets dans une table, elle n'est pas en 3NF par définition;) –

Répondre

18

Essayez ceci - il supprime tous les doublons de votre table:

;WITH duplicates AS 
(
    SELECT 
     ProductID, ProductName, Description, Category, 
     ROW_NUMBER() OVER (PARTITION BY ProductID, ProductName 
          ORDER BY ProductID) 'RowNum' 
    FROM dbo.tblProduct 
) 
DELETE FROM duplicates 
WHERE RowNum > 1 
GO 

SELECT * FROM dbo.tblProduct 
GO 

Vos doublons doivent être maintenant disparu: la sortie est:

ProductID ProductName DESCRIPTION  Category 
    1   Cinthol   cosmetic soap  soap 
    1   Lux    cosmetic soap  soap 
    1   Crowning Glory cosmetic soap  soap 
    2   Cinthol   nice soap   soap 
    3   Lux    nice soap   soap 
+2

+1: Drats - battu –

+0

Nice Marc_s, est-ce une requête CTE? Si oui, n'est-il pas nécessaire dans une requête CTE d'avoir une clause 'union'? – TCM

+0

@Nitesh Panchal: oui, les CTE sont l'une des fonctionnalités sous-utilisées de SQL Server - tout comme la clause OVER() :-) –

0

Première utilisation d'un SELECT... INTO:

SELECT DISTINCT ProductID, ProductName, Description, Category 
    INTO tblProductClean 
    FROM tblProduct 

La baisse de la première table.

+5

De l'OP: "Peut-on le faire sans créer de tables temporaires? Juste en une seule requête?" – dcp

4
DELETE tblProduct 
FROM tblProduct 
LEFT OUTER JOIN (
    SELECT MIN(ProductId) as ProductId, ProductName, Description, Category 
    FROM tblProduct 
    GROUP BY ProductName, Description, Category 
) as KeepRows ON 
    tblProduct.ProductId= KeepRows.ProductId 
WHERE 
    KeepRows.ProductId IS NULL 

volés de How can I remove duplicate rows?

MISE À JOUR:

Cela ne fonctionnera que si ProductId est une clé primaire (ce qui ne l'est pas). Il vaut mieux utiliser la méthode de @marc_s, mais je vais laisser cela au cas où quelqu'un utilisant un PK se trouverait sur ce post.

+1

@Abe: 'rowid' était la clé primaire de la table; Je pensais que c'était la syntaxe Oracle pendant un moment jusqu'à ce que j'ai vu le lien. –

+0

Je supposais que ProductId était une clé primaire dans sa table. Je l'ai mis à jour avec ses noms de colonnes pour éviter toute confusion. –

+0

Nice Abe Miessler. Voté – TCM

1

J'ai dû faire cela il y a quelques semaines ... quelle version de SQL Server utilisez-vous? Dans SQL Server 2005 et, vous pouvez utiliser ROW_NUMBER dans le cadre de votre sélection, et sélectionnez seulement où ROW_NUMBER est 1. J'oublie la syntaxe exacte, mais il est bien documenté ... quelque chose le long des lignes de:

Select t0.ProductID, 
     t0.ProductName, 
     t0.Description, 
     t0.Category 
Into tblCleanData 
From (
    Select ProductID, 
      ProductName, 
      Description, 
      Category, 
      Row_Number() Over (
       Partition By ProductID, 
          ProductName, 
          Description, 
          Category 
       Order By  ProductID, 
          ProductName, 
          Description, 
          Category 
      ) As RowNumber 
    From MyTable 
) As t0 
Where t0.RowNumber = 1 

Découvrez http://msdn.microsoft.com/en-us/library/ms186734.aspx, cela devrait vous aider à aller dans la bonne direction.

+1

Vrai, mais l'OP a besoin d'une instruction DELETE ... –

+0

@OMG Poneys - Er, bon point. – BenAlabaster

+0

+1 Ben si .. – TCM

Questions connexes