2010-12-17 91 views
1

長話短說,我接管了一個項目,並且數據庫中的表格非常需要重複刪除。該表如下所示:SQL Server 2008重複數據刪除

supply_req_id | int  | [primary key] 
supply_req_dt | datetime | 
request_id | int  | [foreign key] 
supply_id  | int  | [foreign key] 
is_disabled | bit  | 

重複記錄具有相同的request_id和supply_id。我想找到一個最佳實踐方式來消除這張桌子。

[編輯]
@Kirk_Broadhurst,謝謝你的提問。由於supply_req_id在其他地方沒有引用,我會回答說保留第一個,刪除任何後續的發生。

節日快樂

+1

當你發現一個重複的,你將如何定值> 1

;WITH cDupes AS ( SELECT supply_req_id, ROW_NUMBER() OVER (PARTITION BY supply_req_dt, request_id ORDER BY supply_req_id) AS RowNum FROM MyTable ) DELETE cDupes WHERE RowNum > 1 

然後添加一個唯一約束或索引,其中一至「保持」並刪除? – 2010-12-17 04:22:24

回答

3

這會爲(supply_req_dt,request_id)分組中的每行創建一個排名,從1開始= supply_req_id最低。任何欺騙有

CREATE UNIQUE INDEX IXU_NoDupes ON MyTable (supply_req_dt, request_id) 
2

好像應該是這樣的命令,但也許是因爲我已經習慣了不同的數據庫服務器。以下是相關的支持DOC:

如何從一個表中的SQL Server刪除重複的行 http://support.microsoft.com/kb/139444

2

你需要澄清你的規則來確定哪些記錄保持在一個「匹配」的情況下 - 最最近的,最早的,那個有is_disabled的真的,還是假的?

一旦你已經確定了規則,剩下的就是相當簡單:

  1. 選擇要保存記錄 - 在distinct記錄
  2. 加入回到原來的表來獲得這些的ID記錄。
  3. 刪除everthing不在連接的數據集中。

那麼,假設您想保留任何「重複」對的最新記錄。您的查詢應該是這樣的:

DELETE FROM [table] WHERE supply_req_id NOT IN 
(SELECT supply_req_id from [table] t 
INNER JOIN 
    (SELECT MAX(supply_req_dt) dt, request_id, supply_id 
    FROM [table] 
    GROUP BY request_id, supply_id) d 
ON t.supply_req_dt = d.dt 
AND t.request_id = d.request_id 
AND t.supply_id = d.supply_id) 

美中不足的是,如果supply_req_dt還將被複制,那麼你會保持兩個重複的。解決方法是做另一group by並選擇頂部id

select MAX(supply_req_id), supply_req_dt, request_id, supply_id 
group by supply_req_dt, request_id, supply_id 

作爲一箇中間步驟。但如果你不需要這樣做,不要打擾它。