Redshift: ОШИБКА: целевая таблица должна быть частью предиката equijoin - PullRequest
0 голосов
/ 26 апреля 2018

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

Подойдя к вопросу,

Я пытаюсь объединить две таблицы и выполнить обновление. Вот мой запрос:

UPDATE table1 SET f1 = table2.f1,f2 = table2.f2,f3 = table2.f3 FROM table2 where (table1.f1 = table2.f1 OR (table1.f1 is null and table2.f1 is null)) AND (table1.f2 = table2.f2 OR (table1.f2 is null and table2.f2 is null))

Для этого запроса я получаю сообщение об ошибке: ОШИБКА: целевая таблица должна быть частью предиката equijoin.

Но, как я вижу, таблица целей уже используется в equijoin, почему я получаю эту ошибку? Более того, мне нужно сопоставить как исходные, так и целевые значения NULL, поэтому я использую is null check. Если я пропущу это и выполню обычный запрос соединения, как показано ниже, это не даст никакой ошибки.

UPDATE table1 SET f1 = table2.f1,f2 = table2.f2,f3 = table2.f3 FROM table2 where table1.f1 = table2.f1 AND table1.f2 = table2.f2

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

Просто из любопытства я попробовал пару запросов в красном смещении.

1. UPDATE table1 SET f1 = table2.f1,f2 = table2.f2,f3 = table2.f3 FROM table2 where (table1.f1 = table2.f1 OR (table1.f1 is null and table2.f1 is null)) -- Failed with same error.

2. UPDATE table1 SET f1 = table2.f1,f2 = table2.f2,f3 = table2.f3 FROM table2 where (table1.f1 = table2.f1 OR (table1.f1 is null and table2.f1 is null)) AND (table1.f2 = table2.f2) -- Passed

3. UPDATE table1 SET f1 = table2.f1,f2 = table2.f2,f3 = table2.f3 FROM table2 where (table1.f1 = table2.f1 OR (table1.f1 is null and table2.f1 is null)) OR (table1.f2 = table2.f2) -- Failed with same error

Похоже, что оно выходит из строя только тогда, когда последнее условие OR, и проходит, когда оно AND, очень, очень, очень удивительно.

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

Предикат equijoin строго, когда у вас есть только оператор =, и при наличии нескольких условий это может быть только пересечение (вы можете использовать только AND, а не OR). Я не знаю точно, почему это реализовано таким образом, но я полагаю, что у этого есть веские причины, связанные с распараллеливанием. Более сложная логика требует материализации ее через подзапрос.

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

0 голосов
/ 26 апреля 2018

Это работает?

UPDATE table1
     SET f1 = table2.f1,f2 = table2.f2,f3 = table2.f
     FROM table2 
     WHERE table1.f1 = table2.f1 AND
           (table1.f2 = table2.f2 OR (table1.f2 is null and table2.f2 is null));

Если это так, вы можете разбить это на несколько обновлений.

...