SQL Server 2008重复数据删除

时间:2010-12-17 03:53:24

标签: tsql sql-server-2008 deduplication

长话短说,我接手了一个项目,数据库中的表格非常需要重复删除。该表如下所示:

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,我会回答说保留第一个,删除任何后续的出现。

节日快乐

3 个答案:

答案 0 :(得分:3)

这将为(supply_req_dt,request_id)分组中的每一行创建一个等级,从1 =最低的supply_req_id开始。任何欺骗的值都> 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

然后添加唯一约束或INDEX

CREATE UNIQUE INDEX IXU_NoDupes ON MyTable (supply_req_dt, request_id)

答案 1 :(得分:2)

似乎应该有一个命令,但也许那是因为我习惯了不同的数据库服务器。这是相关的支持文档:

如何从SQL Server中的表中删除重复的行 http://support.microsoft.com/kb/139444

答案 2 :(得分:2)

你需要澄清你的规则,以确定在“匹配”的情况下要保留哪条记录 - 最新的,最早的,is_disabled为真的还是假的?

一旦确定了该规则,剩下的就相当简单了:

  1. 选择您要保留的记录 - distinct记录
  2. 加入原始表格以获取这些记录的ID。
  3. 删除不在已连接数据集中的内容。
  4. 因此,假设您希望保留任何“重复”对的最新记录。您的查询将如下所示:

    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 
    

    作为临时步骤。但如果您不需要这样做,请不要理会它。