Ponieważ null =null ocenia jako false musisz sprawdzić, czy oba pola są null oprócz sprawdzenia równości:
UPDATE table_one SET table_one.x = table_two.y
FROM table_two
WHERE
(table_one.invoice_number = table_two.invoice_number
OR (table_one.invoice_number is null AND table_two.invoice_number is null))
AND
(table_one.submitted_by = table_two.submitted_by
OR (table_one.submitted_by is null AND table_two.submitted_by is null))
AND
-- etc
Możesz również użyć kodu <>połączenie funkcja, która jest bardziej czytelna:
UPDATE table_one SET table_one.x = table_two.y
FROM table_two
WHERE
coalesce(table_one.invoice_number, '') = coalesce(table_two.invoice_number, '')
AND coalesce(table_one.submitted_by, '') = coalesce(table_two.submitted_by, '')
AND -- etc
Musisz jednak uważać na wartości domyślne (ostatni argument zjednoczenia ).
Typ danych powinien odpowiadać typowi kolumny (aby nie skończyć na przykład na porównywaniu dat z liczbami) i domyślnie powinien być taki, aby nie pojawiał się w danych
Np. coalesce(null, 1) =coalesce(1, 1) to sytuacja, której chciałbyś uniknąć.
Aktualizacja (dotyczące wydajności):
Skanowanie sekw. na table_two - to sugeruje, że nie masz żadnych indeksów na table_two .
Więc jeśli zaktualizujesz wiersz w table_one następnie znaleźć pasujący wiersz w table_two baza danych w zasadzie musi przeszukiwać wszystkie wiersze jeden po drugim, aż znajdzie dopasowanie.
Pasujące wiersze można znaleźć znacznie szybciej, jeśli odpowiednie kolumny zostałyby zindeksowane.
Z drugiej strony, jeśli table_one ma jakieś indeksy, które spowalniają aktualizację.
Zgodnie z ten przewodnik po wydajności
:
Inna pomocna sugestia z tego samego przewodnika to:
Na przykład, jeśli table_one id możesz dodać coś takiego jak
and table_one.id between x and y
do gdzie warunku i uruchom zapytanie kilka razy zmieniając wartości x i y aby wszystkie rzędy były zakryte.
Możesz być ostrożny podczas korzystania z ANALIZA opcja z EXPLAIN w przypadku oświadczeń z efektami ubocznymi.Zgodnie z dokumentacją
: