Tsql SQL Server 2008重复数据消除
长话短说,我接管了一个项目,数据库中的一个表非常需要重复数据消除。该表如下所示:Tsql SQL Server 2008重复数据消除,tsql,sql-server-2008,deduplication,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 | DELETE FROM [table] WHERE supp
supply_req_id | int | [primary key]
supply_req_dt | datetime |
request_id | int | [foreign key]
supply_id | int | [foreign key]
is_disabled | bit |
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)
重复存在于具有相同请求id和提供id的记录中。我想找到消除此表重复的最佳实践方法
[编辑]@柯克·布罗德赫斯特,谢谢你的提问。由于supply_req_id没有在其他任何地方引用,因此我的回答是保留第一个,删除任何后续事件
“快乐假日”似乎应该有一个用于此的命令,但可能是因为我习惯了另一个数据库服务器。以下是相关的支持文档: 如何在SQL Server中从表中删除重复行
似乎应该有一个用于此的命令,但可能是因为我习惯了另一个数据库服务器。以下是相关的支持文档: 如何在SQL Server中从表中删除重复行
您需要澄清您的规则,以确定在“匹配”情况下要保留的记录-最新的、最早的、禁用了
的记录是正确的还是错误的
一旦确定了该规则,剩下的就相当简单了:
选择要保留的记录-不同的记录
连接回原始表以获取这些记录的ID
删除所有不在联接数据集中的内容
假设您想保留任何“重复”对的最新记录。您的查询如下所示:
supply_req_id | int | [primary key]
supply_req_dt | datetime |
request_id | int | [foreign key]
supply_id | int | [foreign key]
is_disabled | bit |
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
也被复制,那么您将保留这两个副本。修复方法是执行另一个groupby
,然后选择顶部的id
select MAX(supply_req_id), supply_req_dt, request_id, supply_id
group by supply_req_dt, request_id, supply_id
作为过渡步骤。但是如果你不需要这样做,就不用费心了。你需要澄清你的规则,以确定在“匹配”的情况下保留哪一条记录——最近的、最早的、禁用了的记录是正确的还是错误的
一旦确定了该规则,剩下的就相当简单了:
选择要保留的记录-不同的记录
连接回原始表以获取这些记录的ID
删除所有不在联接数据集中的内容
假设您想保留任何“重复”对的最新记录。您的查询如下所示:
supply_req_id | int | [primary key]
supply_req_dt | datetime |
request_id | int | [foreign key]
supply_id | int | [foreign key]
is_disabled | bit |
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
也被复制,那么您将保留这两个副本。修复方法是执行另一个groupby
,然后选择顶部的id
select MAX(supply_req_id), supply_req_dt, request_id, supply_id
group by supply_req_dt, request_id, supply_id
作为过渡步骤。但是,如果您不需要这样做,就不用麻烦了。这将为(supply\u req\u dt,request\u id)分组中的每一行创建一个列组,从1=最低supply\u req\u id开始。任何dupe的值都大于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
然后添加唯一的约束或索引
CREATE UNIQUE INDEX IXU_NoDupes ON MyTable (supply_req_dt, request_id)
这将为(supply_req_dt,request_id)分组中的每一行创建一个列组,从1=最低supply_req_id开始。任何dupe的值都大于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
然后添加唯一的约束或索引
CREATE UNIQUE INDEX IXU_NoDupes ON MyTable (supply_req_dt, request_id)
当您发现一个副本时,您将如何决定“保留”哪一个和删除哪一个?当您发现一个副本时,您将如何决定“保留”哪一个和删除哪一个?