如何使用SSIS从平面文件中删除重复的行?

时间:2008-09-29 21:27:05

标签: sql-server ssis duplicates business-intelligence duplicate-removal

首先我要说的是,能够从平面文件中获取1700万条记录,推送到远程盒子上的数据库并花费7分钟是令人惊讶的。 SSIS真的太棒了。但是现在我有那些数据,如何删除重复数据?

更好的是,我想取平面文件,从平面文件中删除重复项并将它们放回另一个平面文件中。

我正在考虑:

Data Flow Task

  • 文件来源(带有关联的文件连接)
  • for for loop container
  • 包含一些逻辑的脚本容器,用于判断是否存在另一行

Thak你,这个网站上的每个人都非常了解。

Update: I have found this link, might help in answering this question

9 个答案:

答案 0 :(得分:22)

使用排序组件。

只需选择要对已加载行进行排序的字段,在左下角,您将看到一个复选框以删除重复项。此框仅根据排序条件删除任何重复的行 因此,在下面的示例中,如果我们仅对第一个字段进行排序,则行将被视为重复:

1 | sample A |
1 | sample B |

答案 1 :(得分:6)

我建议使用SSIS将记录复制到临时表中,然后创建一个根据您的情况使用Select Distinct或Rank的任务来选择将它们汇总到平面文件并从临时表中删除它们的重复项。最后一步是将临时表中的记录复制到目标表中。

确定重复是SQL擅长的,但平面文件不太适合。在您提议的情况下,脚本容器将加载一行,然后必须将其与1700万条记录进行比较,然后加载下一行并重复...性能可能不是那么好。

答案 2 :(得分:4)

平面文件来源 - >聚合(按列要分组) - >平面文件目的地

答案 3 :(得分:2)

策略通常取决于登台表的列数。列越多,解决方案就越复杂。你链接的文章有一些非常好的建议。

我将添加到目前为止所有其他人所说的内容中,唯一的事情就是具有日期和日期时间值的列将提供此处介绍的一些解决方案。

我想出的一个解决方案是:

SET NOCOUNT ON

DECLARE @email varchar(100)

SET @email = ''

SET @emailid = (SELECT min(email) from StagingTable WITH (NOLOCK) WHERE email > @email)

WHILE @emailid IS NOT NULL
BEGIN

    -- Do INSERT statement based on the email
    INSERT StagingTable2 (Email)
    FROM StagingTable WITH (NOLOCK) 
    WHERE email = @email

    SET @emailid = (SELECT min(email) from StagingTable WITH (NOLOCK) WHERE email > @email)

END

在进行重复数据删除时,这比CURSOR快很多,并且不会挂断服务器的CPU。要使用它,请将来自文本文件的每个列分隔为它们自己的变量。在循环之前和之内使用单独的SELECT语句,然后将它们包含在INSERT语句中。这对我来说非常好。

答案 4 :(得分:2)

要在平面文件上执行此操作,我使用unix命令行工具sort:

sort -u inputfile > outputfile

不幸的是,windows sort命令没有唯一的选项,但您可以尝试从以下选项之一下载排序实用程序:

(我没试过,所以没有保证,我害怕)。

另一方面,要在将记录加载到数据库中时执行此操作,可以在数据库表上使用ignore_dup_key创建唯一索引。这将使记录在加载时非常有效。

CREATE UNIQUE INDEX idx1 ON TABLE (col1, col2, ...) WITH IGNORE_DUP_KEY

答案 5 :(得分:2)

一些肮脏的解决方案是使用跨越所有列的复合键设置目标表。这将保证distint唯一性。然后在“数据目标”形状上,配置任务以忽略错误。所有重复的插入都将被遗忘。

答案 6 :(得分:2)

我们可以使用查找表。像SSIS一样提供两个DFS(数据流转换),即模糊分组和模糊查找。

答案 7 :(得分:1)

我建议在目标服务器上加载登台表,然后将结果合并到目标服务器上的目标表中。如果您需要运行任何卫生规则,那么您可以通过存储过程执行此操作,因为您必须获得比通过SSIS数据流转换任务更好的性能。此外,重复数据删除通常是一个多步骤的过程。你可能想要重复数据删除:

  1. 明显的界限。
  2. 不同的列组,如名字,姓氏,电子邮件地址等
  3. 您可能希望对现有目标表进行重复数据删除。如果是这种情况,那么您可能需要包括NOT EXISTS或NOT IN语句。或者您可能希望使用新值更新原始行。通常最好使用MERGE语句和源的子查询。
  4. 获取特定模式的第一行或最后一行。例如,您可能希望每次出现电子邮件地址或电话号码时在文件中输入最后一行。我通常依靠CTE与ROW_NUMBER()生成顺序顺序和反向顺序列,如下面的示例所示:
  5. WITH    
        sample_records 
        (       email_address
            ,   entry_date
            ,   row_identifier
        )
        AS
        (
                SELECT      'tester@test.com'
                        ,   '2009-10-08 10:00:00'
                        ,   1
            UNION ALL
    
                SELECT      'tester@test.com'
                        ,   '2009-10-08 10:00:01'
                        ,   2
    
            UNION ALL
    
                SELECT      'tester@test.com'
                        ,   '2009-10-08 10:00:02'
                        ,   3
    
            UNION ALL
    
                SELECT      'the_other_test@test.com'
                        ,   '2009-10-08 10:00:00'
                        ,   4
    
            UNION ALL
    
                SELECT      'the_other_test@test.com'
                        ,   '2009-10-08 10:00:00'
                        ,   5
        )
    ,   filter_records 
        (       email_address
            ,   entry_date
            ,   row_identifier
            ,   sequential_order
            ,   reverse_order
        )
        AS
        (
            SELECT  email_address
                ,   entry_date
                ,   row_identifier
                ,   'sequential_order'  = ROW_NUMBER() OVER (
                                            PARTITION BY    email_address 
                                            ORDER BY        row_identifier ASC)
                ,   'reverse_order'     = ROW_NUMBER() OVER (
                                            PARTITION BY    email_address
                                            ORDER BY        row_identifier DESC)
            FROM    sample_records
        )
        SELECT      email_address
                ,   entry_date
                ,   row_identifier
        FROM        filter_records
        WHERE       reverse_order = 1
        ORDER BY    email_address;
    

    对于重复数据删除文件有很多选项,但最终我建议您在目标服务器上加载临时表后在存储过程中处理此问题。清理数据后,您可以MERGE或INSERT进入最终目的地。

答案 8 :(得分:1)

发现此页面link text可能值得一看,但有1700万条记录可能需要一段时间太长