SSIS - объединять результаты, только если ключ не существует в первом наборе данных - PullRequest
2 голосов
/ 20 марта 2019

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

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

Какое преобразование мне нужно использовать для достижения этой цели?

Редактировать - вот что у меня есть в моем потоке данных.

enter image description here

Мне нужно добавить преобразование в источник Extract Legacy Item Data, чтобы он удалял записи, чьи коды элементов уже существуют в источнике Extract New Item Data.

Два источника находятся на разных серверах, поэтому я не могу решить, изменив запрос. Я также хотел бы избежать запуска того же запроса, который выполняется в источнике Extract New Item Data.

Ответы [ 3 ]

1 голос
/ 20 марта 2019

Прежде всего, относительно того, что вы используете Назначение SQL Server, я предлагаю прочитать следующий ответ от гуру SSIS @billinkc:


Я предоставлю различные методы для достижения этой цели:

(1) Использование преобразования «Уточняющий запрос»

  1. Вы должны добавитьзадача потока данных, в которой вы добавляете второй инвентарь (устаревший) в качестве источника
  2. Добавьте преобразование поиска, где вы выбираете первый источник инвентаря в качестве таблицы поиска.
  3. Сопоставьте таблицу источника и поиска с помощьюItemCode столбец
  4. В преобразовании поиска выберите Redirect rows to no match output из раскрывающегося списка.
  5. Используйте вывод Lookup no match, чтобы получить нужные строки (не найдено в первомИсточник инвентаря)

Вы можете обратиться по ссылке ниже, она содержит пошаговые руководства.

Полезная ссылка

Старые версии SSIS

Если вы используете старые версии SSIS, вы не найдете раскрывающийся список Redirect rows to no match output,Вместо этого вы должны перейти к выводу «Ошибка поиска», выбрать опцию Redirect Row для ситуации No Match и использовать вывод ошибок для получения нужных строк.


(2) Использование связанных серверов

Во втором списке создайте связанный сервер, чтобы иметь возможность подключиться к первому серверу.Теперь вы можете использовать команду SQL, которая выбирает только строки, не найденные в первом источнике:

SELECT *
FROM Inverntory2
WHERE NOT EXISTS (SELECT 1 FROM <Linked Server>.<database>.<schema>.Inverntory1 Inv1 WHERE Inverntory2.ItemCode = Inv1.ItemCode)

(3) Промежуточная таблица + преобразование MERGE, MERGE JOIN, UNION ALL

В каждой исходной SQL-команде добавьте столбец с фиксированным значением, содержащий идентификатор источника (1,2), например:

SELECT *, 1 as SourceID FROM Inventory

Вы можете объединить оба источника в одном месте назначения, используя одно из перечисленных преобразованийвыше, затем добавьте вторую задачу потока данных, чтобы импортировать отдельные данные из промежуточной таблицы в место назначения на основе столбца ItemCode, например:

SELECT * FROM (
       SELECT *, ROW_NUMBER() OVER(PARTITION BY ItemCode ORDER BY SourceID) rn
       FROM StagingTable ) s
Where s.rn = 1

Затем он вернет все строки из SourceId =1 и новые строки изSourceId = 2

Чтобы узнать больше о слиянии, объединении слиянием и преобразовании UNION ALL, вы можете обратиться по одной из следующих ссылок:


Примечание: проверьте ответ, предоставленный @ userfl89, он содержит очень подробную информацию об использовании преобразования Merge Join и описывает другой подход, который может помочь,Теперь вы должны проверить, какой подход соответствует вашим потребностям.Удачи

0 голосов
/ 21 марта 2019

Пример этого ниже. Использование целевого сервера SQL Server будет работать нормально, однако это позволяет загружать только локальный экземпляр SQL Server, что вы можете рассмотреть в будущем. Хотя поиск обычно работает лучше, объединения слиянием могут быть полезны в определенных обстоятельствах, например, когда в поток данных вводится много дополнительных столбцов, как это может быть сделано с вашими наборами данных. Похоже, что @Hadi рассказал о том, как сделать это с помощью Lookup, поэтому вы можете протестировать оба подхода в непроизводственной среде, имитирующей prod, а затем оценить результаты, чтобы определить лучший вариант.

  • Начните с создания промежуточной таблицы, которая является точным клоном одной из таблиц. Любая таблица будет работать, так как они имеют одинаковое определение. Убедитесь, что все столбцы в промежуточной стадии допускают нулевые значения.
  • Добавьте задачу «Выполнение SQL», чтобы очистить промежуточную таблицу перед задачей «Поток данных» путем усечения или удаления, а затем создания таблицы.
  • Поскольку ItemCode является уникальной сортировкой по этому столбцу в каждом источнике OLE DB. Если вы еще не изменили режим доступа к данным на команду SQL в обоих источниках OLE DB и добавьте предложение ORDER BY для ItemCode. Сделайте это, щелкнув правой кнопкой мыши по источнику OLE DB и перейдя к Показать расширенный редактор > Свойства ввода и вывода > Вывод источника OLE DB > Столбец вывода > затем выберите ItemCode и задайте для свойства SortKeyPosition значение 1 (при условии, что в операторе SQL указан ASC источник).
  • Затем добавьте объединение слиянием в задачу потока данных. Это требует сортировки обоих входов, поэтому входы теперь сортируются. Вы можете сделать это в любом случае, но для этого примера используйте источник OLE DB, который будет использоваться только тогда, когда ItemCode не существует в качестве левого входа объединения слиянием. Используйте левое внешнее соединение и столбец ItemCode в качестве ключа объединения, соединив их, перетаскивая линию из одного в другой в графическом интерфейсе. Добавьте все столбцы из источника OLE DB, который вы хотите использовать, когда один и тот же ItemCode находится в обоих наборах данных (из того, что я могу сказать, это Extract New Item Data, пожалуйста, измените это, если это не так), проверив проверку -боксе рядом с ними в редакторе Merge Join. Используйте префикс выходного псевдонима, который поможет вам их расставить, например X_ItemCode для соответствующих строк.
  • После объединения слиянием добавьте условное разбиение. Это делит записи на основе того, был ли X_ItemCode найден. Для выражения первого вывода используйте функцию ISNULL, чтобы проверить, было ли совпадение из левого внешнего соединения. Например, ISNULL(X_ItemCode) != TRUE указывает, что ItemCode существует в обоих наборах данных. Вы можете назвать этот вывод Matching Rows . Вывод по умолчанию будет содержать несоответствия. Для облегчения различения вы можете переименовать вывод по умолчанию Несоответствующие строки .
  • Подключите вывод Matching Rows к таблице назначения. В этом сопоставляются только столбцы строк, которые были сопоставлены для источника, который вы хотите использовать, когда ItemCode существует в обоих наборах данных, то есть X_ строки с префиксом, такие как X_ItemCode.
  • Добавьте еще одно назначение SQL Server в поток данных и подключите к нему выход Несоответствующие строки со всеми столбцами, сопоставленными из строк, которые не совпадали с . без X_ в этом примере.
  • Вернитесь к потоку управления в пакете, добавьте еще одну задачу потока данных после этой. Используйте промежуточную таблицу в качестве источника OLE DB и таблицу назначения в качестве пункта назначения SQL Server. Сортировка здесь не нужна.
0 голосов
/ 21 марта 2019

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

SELECT Inverntory2.*
FROM Inverntory2 LEFT JOIN Inverntory1
     On Inverntory2.ItemCode = Inverntory1.ItemCode
WHERE Inverntory1.ItemCode IS NULL

ИЛИ

SELECT *
FROM Inverntory2
WHERE NOT EXISTS (SELECT 1 FROM Inverntory1 WHERE Inverntory2.ItemCode = Inverntory1.ItemCode)
...