Большая проблема запроса в MERGE, когда исходная таблица имеет несколько строк для ключей таблицы - PullRequest
0 голосов
/ 05 февраля 2020

Я работаю над проектом по объединению данных из исходной таблицы (zsource) в целевую таблицу (ztarget). Таблица назначения показана ниже:

ztarget : -

a,b,n
a1,b1,10
a2,b2,15

Исходная таблица, которую мы получаем, поступает от инструмента, который захватывает триггеры базы данных и отправляет данные в виде дельта записи. В приведенной ниже таблице DI_SEQUENCE_NUMBER - это последовательность, в которой выполняется операция с БД, а DI_OPERATION_TYPE - это тип операции с (D = удалить, U = обновить, I = вставить).

zsource : -

DI_SEQUENCE_NUMBER,DI_OPERATION_TYPE,a,b,n
0,U,a1,b1,15
1,U,a1,b1,16
2,D,a1,b1,33
3,I,a1,b1,43
4,U,a1,b1,55
5,U,a1,b1,65
0,U,a2,b2,99

Как объединить данные из исходной таблицы (zsource) с целевой таблицей (ztarget) в точной последовательности в исходная таблица. Я попробовал приведенный ниже оператор Merge, но он дает мне ошибку "UPDATE / MERGE должен соответствовать не более одной строки источника для каждой целевой строки"


MERGE zsac_figl01.ztarget T
USING (SELECT * FROM `sap01-188316.zsac_figl01.zsource` ORDER BY DI_SEQUENCE_NUMBER) S
ON 
T.a = S.a and
T.b = S.b 

WHEN MATCHED AND S.DI_OPERATION_TYPE = 'U' THEN
  UPDATE SET 
T.a = S.a,
T.b = S.b
WHEN MATCHED AND S.DI_OPERATION_TYPE = 'D' THEN
  DELETE
WHEN NOT MATCHED BY TARGET THEN
  INSERT 
  (a,b ) 
VALUES
  (a,b )

1 Ответ

0 голосов
/ 05 февраля 2020

Изучив документацию, я обнаружил, что (как я уже говорил в разделе комментариев):

Если строка в обновляемой таблице объединяется с несколькими строками из FROM затем запрос генерирует следующую ошибку времени выполнения: UPDATE / MERGE должен соответствовать не более одной исходной строки для каждой целевой строки.

Это означает, что в TARGET может быть не более одного совпадения. ТАБЛИЦА из каждой строки в ИСТОЧНИК СТОЛ . В вашем случае у вас есть действия, которые должны происходить в одной строке. Другими словами, для одной и той же пары a и b в TARGET TABLE у вас есть более одного совпадения в SOURCE TABLE . Этого не может произойти при использовании MERGE .

Несмотря на это, существует решение вашей проблемы. Вы стремитесь выполнять одно действие за раз, однако учтите, что если вы выполните только последнее действие, вы получите тот же результат. Таким образом, вы можете изменить исходную таблицу , расположенную в вашем операторе USING , чтобы она выполняла только последнее действие / изменение, заказанное DI_SEQUENCE_NUMBER .

Ваш оператор USING выглядит следующим образом:

USING ( SELECT s1.* from `zsource` s1 
      inner join (select MAX(DI_SEQUENCE_NUMBER) as DI_SEQUENCE_NUMBER_MAX, a, b 
                    FROM `zsource` group by a,b
                 ) s2 on s1.a=s2.a and 
                   s1.b=s2.b and 
                   s2.DI_SEQUENCE_NUMBER_MAX = s1.DI_SEQUENCE_NUMBER) S

Я хотел бы отметить, что результат выполнения INNER JOIN :

enter image description here

Это означает, что вы будете рассматривать только последние действия, основанные на DI_SEQUENCE_NUMBER .

Кроме того, я хочу подтвердить ваше использование UPDATE и INSERT . Полагаю, вам следует добавить поле n , иначе вы не измените свои данные, поскольку a1 = a1 и b1 = b1 . Ниже приведен синтаксис:

WHEN MATCHED AND S.DI_OPERATION_TYPE = 'U' THEN
UPDATE SET 
T.a = S.a,
T.b = S.b,
T.n = S.n
WHEN MATCHED AND S.DI_OPERATION_TYPE = 'D' THEN
  DELETE
WHEN NOT MATCHED BY TARGET THEN
  INSERT 
  (a,b,n) 
VALUES
  (a,b,n)

Надеюсь, это поможет.

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