优化全局家庭去重SQL脚本:仅更新未去重记录避免数据覆盖
优化后的全局家庭去重更新脚本
针对你提到的重复更新和数据覆盖问题,我们可以通过精准过滤更新范围和调整去重基准数据源来解决,同时保证只处理未标记的父级记录,基于已确认的唯一数据完成去重。
核心修改点
- 仅更新
IsGlobalFamilyUnique IS NULL且IsChild = 0的记录,彻底避免对已处理行的重复操作 - 子查询中同时包含已标记为
IsGlobalFamilyUnique = 1的父级记录,确保这些唯一数据作为去重分组的基准 - 保留原有的去重逻辑,但通过外层过滤确保不会覆盖已有值
修改后的完整脚本
---------------- -- GLOBAL FAMILY DEDUPLICATION ---------------- -- Global Family Deduplication of parents UPDATE mstr SET IsGlobalFamilyUnique = CASE WHEN rn > 1 THEN 0 -- 因为只处理NULL的行,无需判断IsGlobalFamilyUnique是否为NULL WHEN rn = 1 THEN 1 ELSE IsGlobalFamilyUnique END, GlobalFamilyDupID = [NewGlobalFamilyDupID], GroupIdentifier = ControlNumber FROM ( SELECT ControlNumber, MD5hash, IsGlobalFamilyUnique, GlobalFamilyDupID, TopLvlGuid, GroupIdentifier, -- 以每个MD5分组的第一条ControlNumber作为重复ID(包含已标记的唯一记录) FIRST_VALUE(ControlNumber) OVER (PARTITION BY [MD5Hash] ORDER BY ID) [NewGlobalFamilyDupID], -- 按MD5分组排序,生成行号 ROW_NUMBER() OVER (PARTITION BY [MD5Hash] ORDER BY ID ASC) [RN] FROM ( -- 数据源包含:未标记的父级 + 已标记为唯一的父级(作为去重基准) SELECT * FROM dbo.tblMaster WHERE IsChild = 0 AND (IsGlobalFamilyUnique = 1 OR IsGlobalFamilyUnique IS NULL) ) toDedupe ) mstr -- 只更新未标记的父级记录,彻底避免重复操作和覆盖 WHERE mstr.IsGlobalFamilyUnique IS NULL AND mstr.IsChild = 0;
关键细节说明
- 外层WHERE过滤:这是最关键的优化,直接限定了只有未处理的父级记录才会被更新,完全杜绝了对已有值的覆盖和重复计算。
- 子查询数据源:保留了
IsGlobalFamilyUnique = 1的记录,这样在按MD5分组时,已标记的唯一记录会作为分组的基准,新的重复项会被正确标记为0,且重复ID指向已有的唯一记录。 - CASE语句简化:因为外层已经过滤了
IsGlobalFamilyUnique IS NULL的行,所以CASE里无需再判断IsGlobalFamilyUnique IS NULL,逻辑更简洁。
测试数据验证
用你提供的测试数据运行这个脚本后:
- 只有
ControlNumber为BUL00000001、BUL00000004、BUL00000005、BUL00000006、BUL00000007的父级记录会被处理 - 如果后续再次运行,这些行的
IsGlobalFamilyUnique已经有值,不会被重复更新
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

