SSIS中如何处理非全列数据相同的重复项?
处理SSIS中ID重复但其他列存在差异的重复项
我完全懂你的痛点——Sort+Aggregate组合确实只适合处理全列完全一致的重复项,但遇到像你示例里ID重复、其他字段却有差异的情况(比如ID 33000017672的两行),就得换个思路了。下面给你分享几个实用的解决方案,按需选择就行:
方案一:先标记重复ID,再按需处理
这个方法的核心是先把所有ID重复的行筛选出来,再根据你的业务规则(比如保留特定行、合并字段值)做针对性处理。
- 第一步:用Aggregate统计ID出现次数
把数据源接入Aggregate组件,按ID字段分组,添加一个Count(*)聚合函数,命名为ID_Count。这样就能得到每个ID的出现次数,次数大于1的就是存在重复的ID。 - 第二步:用Lookup关联原数据
把原数据源和Aggregate的输出接入Lookup组件,关联条件设为ID == ID,把ID_Count字段带回原数据流里。 - 第三步:用Conditional Split拆分数据流
添加Conditional Split组件,设置两个分支:- 分支1:
ID_Count > 1——所有ID重复的行(包含全列重复和非全列重复的情况) - 分支2:
ID_Count == 1——无重复的行,直接输出即可
- 分支1:
- 第四步:自定义处理重复行
- 如果想保留每组重复ID里的某一行(比如保留
Talk Time最长的记录):把分支1的数据流接入Sort组件,按ID排序,再按Talk Time降序排列,接着用Script Component或者Row Sampling组件只保留每组的第一行。 - 如果想合并重复行的字段值(比如
Queue Time取最大值、Talk Time求和):把分支1接入Aggregate组件,按ID分组,对其他字段选择合适的聚合函数(MAX、SUM等)。
- 如果想保留每组重复ID里的某一行(比如保留
方案二:用Script Component实时标记重复项
如果你不想走Lookup+Aggregate的流程,也可以直接用Script Component在数据流里实时标记重复的ID行:
- 第一步:接入Script Component(转换组件)
把数据源拖入Script Component,选择“转换”类型。 - 第二步:设置脚本变量与输出列
在脚本的PreExecute方法里定义一个字典,用来记录每个ID的出现次数:
同时在Script Component的“输入和输出”选项里,添加一个布尔类型的输出列private Dictionary<string, int> idCounter; public override void PreExecute() { base.PreExecute(); idCounter = new Dictionary<string, int>(); }IsDuplicate,用来标记是否为重复行。 - 第三步:编写重复标记逻辑
在ProcessInputRow方法里写入判断逻辑:public override void ProcessInputRow(Input0Buffer Row) { string currentId = Row.ID.ToString(); if (idCounter.ContainsKey(currentId)) { idCounter[currentId]++; Row.IsDuplicate = true; } else { idCounter.Add(currentId, 1); Row.IsDuplicate = false; } } - 第四步:拆分处理数据流
用Conditional Split组件把IsDuplicate == true的重复行和非重复行分开,再按你的需求处理重复行即可。
顺带处理全列重复的情况
像你示例里ID 33000017675这种全列完全重复的行,可以在方案一的分支1里再加一层处理:
- 先添加派生列组件,计算整行的校验和:
CHECKSUM(ID, StartDate, EndTime, QueueTime, TalkTime),命名为RowChecksum - 再用Aggregate组件按
ID和RowChecksum分组统计次数,次数大于1的就是全列重复的行,可以直接删除或者只保留一行。
这样就能同时覆盖两种重复场景啦!
内容的提问来源于stack exchange,提问作者Abdulquadir Shaikh
相关产品推荐
相关产品推荐

