Siden null =null
evalueres til falsk
du skal tjekke om to felter begge er null
udover ligestillingstjek:
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
Du kan også bruge
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
Men du skal være forsigtig med standardværdierne (sidste argument for at sammensmelte
).
Den datatype skal matche kolonnetypen (så du ikke ender med at sammenligne datoer med f.eks. tal), og standarden skal være sådan, at den ikke vises i dataene
F.eks. sammensmelte(nul, 1) =samles(1, 1)
er en situation, du gerne vil undgå.
Opdatering (med hensyn til ydeevne):
Seq Scan på table_two
- dette tyder på, at du ikke har nogen indekser på table_two
.
Så hvis du opdaterer en række i table_one
derefter for at finde en matchende række i tabel_to
databasen skal som udgangspunkt scanne gennem alle rækkerne én efter én, indtil den finder et match.
De matchende rækker kunne findes meget hurtigere, hvis de relevante kolonner blev indekseret.
På bagsiden hvis table_one
har nogen indekser, så det bremser opdateringen.
Ifølge denne præstationsvejledning
:
Et andet forslag fra den samme guide, der kan være nyttigt, er:
Så for eksempel hvis table_one
et id
kolonne kan du tilføje noget som
and table_one.id between x and y
til hvor
betingelse og kør forespørgslen flere gange ved at ændre værdierne for x
og y
så alle rækker er dækket.
Du vil måske være forsigtig, når du bruger ANALYSE
mulighed med EXPLAIN
når man har at gøre med udsagn med bivirkninger.Ifølge dokumentation
: