2010-07-27 135 views
7

說我有重複行我表以及我的數據庫設計是第三類: -如何徹底刪除重複的行

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'); 

我只想要1每一行的情況下應該出現在我的表。因此應刪除完全相同的2nd, 3rd and last row。我可以爲此編寫什麼查詢?可以在不創建臨時表的情況下完成嗎?只是在一個單一的查詢?

感謝提前:)

+0

第一個記錄基於插入順序?對於什麼版本的SQL Server? – 2010-07-27 15:41:02

+0

Sql Server 2008. – TCM 2010-07-27 15:42:41

+0

當你說第三課時,我會猜測你的意思是第三範式。如果它允許在一個表中完全重複,它不是按照定義3NF;) – 2010-07-27 15:47:38

回答

18

試試這個 - 它會從表中刪除所有重複:

;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 

你的副本現在應該走了:輸出爲:

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 - 毆打 – 2010-07-27 15:55:53

+0

Nice Marc_s,這是CTE查詢嗎?如果是這樣,CTE查詢中沒有必要有一個'union'子句? – TCM 2010-07-27 15:58:02

+0

@Nitesh Panchal:是的,CTE是SQL Server的未被使用的特性之一 - 就像OVER()子句一樣:-) – 2010-07-27 15:59:29

0

首先使用SELECT... INTO

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

的下降的第一個表。

+5

從OP:「可以在沒有創建臨時表的情況下完成嗎?只需一個查詢?」 – dcp 2010-07-27 15:38:32

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 

被盜從How can I remove duplicate rows?

UPDATE:

這如果ProductID等於主鍵(它不是)纔有效。你最好使用@marc_s'方法,但是我會留下這個以防萬一有人使用PK會遇到這篇文章。

+1

@Abe:'rowid'是表格的主鍵;我認爲這是Oracle語法片刻,直到我看到鏈接。 – 2010-07-27 15:43:17

+0

我假設ProductId是他的表中的主鍵。我用他的專欄名稱更新了它,以幫助避免任何混淆。 – 2010-07-27 16:01:55

+0

尼斯安倍Miessler。投票 – TCM 2010-07-27 16:06:43

1

我不得不在幾個星期前做這個......你正在使用什麼版本的SQL Server?在SQL Server 2005和了,你可以使用ROW_NUMBER爲您選擇的一部分,並且只能選擇其中ROW_NUMBER爲1。我忘了確切的語法,但它是有據可查......沿着線的東西:

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 

退房http://msdn.microsoft.com/en-us/library/ms186734.aspx,這應該讓你朝着正確的方向前進。

+1

是的,但OP需要DELETE語句... – 2010-07-27 15:46:16

+0

@OMG小馬 - 呃,好點。 – BenAlabaster 2010-07-27 15:54:42

+0

+1 Ben雖然.. – TCM 2010-07-27 16:05:36