Как удалить дубликаты строк из плоского файла с помощью служб SSIS? - PullRequest
6 голосов
/ 30 сентября 2008

Позвольте мне вначале сказать, что возможность взять 17 миллионов записей из плоского файла, отправить их в удаленную систему на БД и занять 7 минут - это удивительно. SSIS действительно фантастический. Но теперь, когда у меня есть эти данные, как мне удалить дубликаты?

Еще лучше, я хочу взять плоский файл, удалить дубликаты из плоского файла и поместить их обратно в другой плоский файл.

Я думаю о:

Data Flow Task

  • Источник файла (с соответствующим подключением к файлу)
  • A для петлевого контейнера
  • Контейнер сценария, который содержит некоторую логику, чтобы сказать, существует ли другая строка

Спасибо, и все на этом сайте невероятно осведомлены.

Update: Я нашел эту ссылку, может помочь в ответе на этот вопрос

Ответы [ 9 ]

22 голосов
/ 06 марта 2009

Использовать компонент сортировки.

Просто выберите, по каким полям вы хотите отсортировать загруженные строки, и в левом нижнем углу вы увидите флажок для удаления дубликатов. В этом поле удаляются все строки, которые являются дубликатами, только на основании критериев сортировки. поэтому в приведенном ниже примере строки будут считаться дублирующими, если мы отсортируем только по первому полю:

1 | sample A |
1 | sample B |
6 голосов
/ 30 сентября 2008

Я бы предложил использовать SSIS для копирования записей во временную таблицу, а затем создать задачу, которая использует Select Distinct или Rank в зависимости от вашей ситуации, чтобы выбрать дубликаты, которые будут перенаправлять их в плоский файл, и удалять их из временной таблицы. , Последним шагом будет копирование записей из временной таблицы в таблицу назначения.

Определение дубликата - это то, что хорошо для SQL, но для плоского файла это не так хорошо. В случае, если вы предложите, контейнер сценариев загрузит строку, а затем должен будет сравнить ее с 17 миллионами записей, затем загрузить следующую строку и повторить ... Производительность может быть не такой уж высокой.

4 голосов
/ 11 июня 2009

Источник плоского файла -> Агрегировать (группировать по столбцам, которые вы хотите уникальные) -> Назначение плоского файла

2 голосов
/ 11 октября 2011

Мы можем использовать справочные таблицы для этого. Подобно SSIS предоставляет два DFS (преобразования потока данных), то есть нечеткой группировки и нечеткого поиска.

2 голосов
/ 07 декабря 2008

Немного грязного решения - настроить целевую таблицу с помощью составного ключа, охватывающего все столбцы. Это гарантирует исключительную уникальность. Затем в форме «Назначение данных» настройте задачу на игнорирование ошибок. Все дубликаты вставок исчезнут.

2 голосов
/ 30 сентября 2008

Чтобы сделать это для плоского файла, я использую инструмент командной строки unix, сортировка:

sort -u inputfile > outputfile

К сожалению, команда сортировки windows не имеет уникальной опции, но вы можете попробовать загрузить утилиту сортировки из одного из них:

(я не пробовал их, так что никаких гарантий, боюсь).

С другой стороны, чтобы сделать это при загрузке записей в базу данных, вы можете создать уникальный индекс для ключа таблицы базы данных с помощью ignore_dup_key. Это сделает записи уникальными очень эффективно во время загрузки.

CREATE UNIQUE INDEX idx1 ON TABLE (col1, col2, ...) WITH IGNORE_DUP_KEY
2 голосов
/ 30 сентября 2008

Стратегия обычно зависит от того, сколько столбцов имеет промежуточная таблица. Чем больше столбцов, тем сложнее решение. В статье, на которую вы ссылаетесь, есть несколько очень полезных советов.

Единственное, что я добавлю к тому, что до сих пор говорили все остальные, - это то, что столбцы со значениями даты и даты и времени дадут некоторые решения, представленные здесь.

Одно решение, которое я придумал, это:

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 и не привязывает ЦП сервера. Чтобы использовать это, разделите каждый столбец из текстового файла на свои собственные переменные. Используйте отдельный оператор SELECT до и внутри цикла, затем включите их в оператор INSERT. Это сработало очень хорошо для меня.

1 голос
/ 29 июля 2010

Нашли эту страницу текст ссылки , возможно, стоит посмотреть, хотя с 17 миллионами записей это может занять слишком много времени

1 голос
/ 08 октября 2009

Я бы рекомендовал загрузить промежуточную таблицу на конечном сервере, а затем объединить результаты в целевую таблицу на конечном сервере. Если вам необходимо выполнить какие-либо правила гигиены, вы можете сделать это с помощью хранимой процедуры, поскольку вы обязаны получить лучшую производительность, чем с помощью задач преобразования потока данных служб SSIS. Кроме того, дедупликация - это, как правило, многоэтапный процесс. Вы можете захотеть дедупликации на:

  1. Отдельные линии.
  2. Различных групп столбцов, таких как имя, фамилия, адрес электронной почты и т. Д.
  3. Возможно, вы захотите выполнить дедупликацию против существующей целевой таблицы. Если это так, то вам может потребоваться включить операторы NOT EXISTS или NOT IN. Или вы можете обновить исходную строку новыми значениями. Обычно это лучше всего использовать с оператором MERGE и подзапросом для источника.
  4. Возьмите первый или последний ряд определенного шаблона. Например, вы можете захотеть ввести последнюю строку в файл для каждого вхождения адреса электронной почты или номера телефона. Я обычно полагаюсь на CTE с ROW_NUMBER () для генерации столбцов последовательного и обратного порядка, как в следующем примере:

.

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, либо ВСТАВИТЬ в свой конечный пункт назначения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...