查找重复项并使用其首次找到的副本ID标记重复项

时间:2016-01-24 06:33:54

标签: sql-server tsql sql-update

我有一个名为log的表,其中有数百万行。目前,它看起来像这样:

Id       OriginId MetricId  Value  IsDuplicate DuplicateId
-------- -------- --------- ------ ----------- -----------
1        50ECC7F6 FC7A477F  2.00   0           0
3        50ECC7F6 FC7A477F  2.00   0           0
4        8800B985 7F438F09  5.00   0           0
5        50ECC7F6 FC7A477F  2.00   0           0

我现在需要找到OriginIdMetricId相等的重复项,除了第一项匹配以外的所有匹配项IsDuplicate设置为1,DuplicateId设置为第一个发生行的Id

预期结果是这样的:

Id       OriginId MetricId  Value  IsDuplicate DuplicateId
-------- -------- --------- ------ ----------- -----------
1        50ECC7F6 FC7A477F  2.00   0           0
3        50ECC7F6 FC7A477F  0.00   1           1
4        8800B985 7F438F09  5.00   0           0
5        50ECC7F6 FC7A477F  0.00   1           1

考虑到表格中的行数,挑战是尽可能高效地完成这项工作。

任何建议都非常感谢。谢谢!

1 个答案:

答案 0 :(得分:4)

使用带有原始表和派生表之间的内部联接的更新语句应该非常快,只要你有适当的索引(你可以将更新语句复制到SSMS,然后单击ctrl + L,这将显示估计的执行计划。如果需要索引,您将在结果窗格的顶部看到它。)

创建并填充样本表:

CREATE TABLE tblLog
(
    Id int identity(1,1),
    OriginId varchar(10),
    MetricId varchar(10), 
    Value numeric(10,2),
    IsDuplicate bit null default 0,
    DuplicateId int null default 0
)

INSERT INTO tblLog (OriginId, MetricId, Value) VALUES
('50ECC7F6', 'FC7A477F', 2.00),
('50ECC7F6', 'FC7A477F', 2.00),
('8800B985', '7F438F09', 5.00),
('50ECC7F6', 'FC7A477F', 2.00)

以下是更新声明:

UPDATE tblLog
SET IsDuplicate = 1,
    DuplicateId = dupId
FROM tblLog INNER JOIN
(
    SELECT MIN(Id) as dupId, OriginId as oid, MetricId as mid
    FROM tblLog
    GROUP BY OriginId, MetricId
) orig
ON OriginId = oid and MetricId = mid and id > dupId

测试结果:

SELECT *
FROM tblLog 

清理

DROP table tblLog