2010-12-17 92 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 

作为一个中间步骤。但如果你不需要这样做,不要打扰它。