【问题标题】:Find duplicates and mark duplicates with its first found duplicate's Id查找重复项并使用第一个找到的重复项的 ID 标记重复项
【发布时间】:2016-01-24 06:33:53
【问题描述】:

我有一个名为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

考虑到表中的行数,挑战在于尽可能高效地执行此操作。

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

【问题讨论】:

  • 你自己试过吗?你想出了什么 SQL 语句?如果您真的陷入困境并想针对这种情况发布关于 SO 的问题,请阅读How to post a T-SQL question on a public forum
  • @TT 我完全认识到我的帖子可能比实际内容更详细。然而,我认为目标非常明确,一些关于我如何解决问题的指示会比我应该如何撰写问题更有帮助。我相信这些 cmets 和期望是阻止某些人(至少是我)更频繁地使用 SO 的原因。
  • 至少不要让某人试图帮助您编写数据表的设置和数据插入。这就是链接的内容。你需要帮助......当然,但至少让那些想要帮助你的人更容易。 Cf How do I ask a good question? - 帮助其他人重现问题 > 包含足够的代码以允许其他人重现问题(在这种情况下设置表 + 数据插入)。
  • 如果以效率为目标,您是否考虑过只使用DuplicateId 列并允许无重复行的空值?

标签: sql-server tsql sql-update


【解决方案1】:

在原始表和派生表之间使用带有内部连接的更新语句应该非常快,前提是您有适当的索引(您可以将更新语句复制到 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

【讨论】:

  • 谢谢@ATC,按预期工作。非常感谢。
猜你喜欢
  • 2011-07-14
  • 2017-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-19
  • 2021-12-11
相关资源
最近更新 更多