SSIS - 将重复列设置为空
Posted
技术标签:
【中文标题】SSIS - 将重复列设置为空【英文标题】:SSIS - Set duplicate columns to null 【发布时间】:2020-11-30 12:01:43 【问题描述】:我有来自平面文件的数据(客户端发送给我,无法编辑),其中有一些重复的电子邮件地址,我想将其设置为 null。我们的软件需要一个唯一的电子邮件地址,所以当它遇到重复时,它会失败。我们的开发人员正在努力纠正这个问题,但与此同时,我想将重复的电子邮件设置为空。这是一个例子:
Client ID | Client Name | Email address
1234 | Mike Smith | MikeSmith@MikesMotors.com
5678 | Mike's Motors | MikeSmith@MikesMotors.com
所以在上面的例子中,我希望两行都进入数据库,但我想将其中一个的电子邮件地址设置为空,但不能同时设置。
【问题讨论】:
确认一下,多封邮件是坏的,多空是好的? 【参考方案1】:所以,我找到了一个“低技术”的解决方案。我使用了多播然后排序。然后我按电子邮件字段排序并将其设置为删除重复记录。我取消选中排序传递中的所有列,除了电子邮件字段和连接键。然后,我使用左连接将其重新加入数据流,获取除了连接左侧的电子邮件字段和右侧的电子邮件字段之外的所有字段。
【讨论】:
【参考方案2】:SSIS 数据流中没有本机组件可以完成此操作。问题是,数据流引擎是一个速度惊人的数据处理器,但它通常只知道 this 行。不是它之前的那个,不是后面的行 - 只是当前行(并且它有许多只知道它们的行的仆从同时运行)。
聚合运算符和缓存查找可能会被黑客入侵以执行此操作,但您将不得不双重处理文件。启动数据流将是源 -> 聚合组件 -> 缓存目标。您按电子邮件地址分组,然后在聚合组件中最小或最大客户端 ID。当我输入它时,我大脑中一个琐碎的部分说聚合和字符串字段存在一个愚蠢的限制。也许只是你不能最小化/最大化它们,但允许分组。我假设 ClientID 和电子邮件地址是唯一的。如果 ClientId 123 同时具有 mike.smith@mail.com 和 mike.smith@gmail.com,则此方法将有效,但您需要更好的机制来确定数据存活率。
因此启动数据流运行,并且您拥有一个缓存,其中包含唯一的电子邮件地址和您希望为其保留电子邮件地址的客户端 ID。
在现有数据流中,我们将忽略源中的电子邮件地址。您可以取消映射,使其永远不会进入行缓冲区,或者记住我们需要查找中的电子邮件地址。在源和目标之间添加查找转换。使用缓存连接管理器对其进行配置,并使用我们刚刚在启动步骤中创建/填充的 CCM。表示在不匹配的情况下,忽略失败。将数据流缓冲区中的客户端 ID 映射到 CCM 中的客户端 ID 列。检查来自 CCM 的电子邮件地址,以便它在数据流缓冲区中可用。假设我们称之为 EmailAddress_LKP
在您的目标中,将 EmailAddress 列映射到查找生成的值 EmailAddress_LKP
另一种方法是编写一个异步脚本组件(异步是您可以访问比当前缓冲区更多但以内存和速度为代价的唯一方法)。在那里,您可能会构建一个看到的电子邮件地址的映射,如果您有匹配项,请指定输出缓冲区的列的 IsNull 属性为 true
【讨论】:
【参考方案3】:您可以使用 row_number 函数找出重复项并将它们归零
这是一种方法
;
WITH mycte
AS (
SELECT 1234 ClientID
,'Mike Smith' ClientName
,'MikeSmith@MikesMotors.com' Emailaddress
UNION ALL
SELECT 5678
,'Mikes Motors'
,'MikeSmith@MikesMotors.com'
)
SELECT ClientID
,ClientName
,CASE
WHEN ROW_NUMBER() OVER (PARTITION BY Emailaddress ORDER BY Emailaddress) > 1
THEN NULL
ELSE Emailaddress
END AS Emailaddress
FROM mycte
【讨论】:
这假定数据已加载到临时表中 @KeithL SSIS 被标记。没有理由不能这样做!即使没有 SSIS,您也可以在一个查询中执行此操作而无需任何临时表以上是关于SSIS - 将重复列设置为空的主要内容,如果未能解决你的问题,请参考以下文章