PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Istruzione di aggiornamento utilizzando una clausola WHERE che contiene colonne con valori null

Poiché null = null restituisce false devi controllare se due campi sono entrambi null oltre al controllo di uguaglianza:

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

Puoi anche usare il coalesce funzione più leggibile:

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

Ma devi stare attento ai valori predefiniti (ultimo argomento per coalesce ).
Il tipo di dati deve corrispondere al tipo di colonna (in modo da non dover confrontare le date con i numeri, ad esempio) e l'impostazione predefinita dovrebbe essere tale da non apparire nei dati
Es. coalesce(null, 1) = coalesce(1, 1) è una situazione che vorresti evitare.

Aggiornamento (relativo alle prestazioni):

Seq Scan on table_two - questo suggerisce che non hai indici su table_two .
Quindi, se aggiorni una riga in table_one quindi per trovare una riga corrispondente in table_two il database in pratica deve scansionare tutte le righe una per una finché non trova una corrispondenza.
Le righe corrispondenti potrebbero essere trovate molto più velocemente se le colonne pertinenti fossero indicizzate.

Sul rovescio della medaglia se table_one ha degli indici che rallentano l'aggiornamento.
Secondo questa guida alle prestazioni :

Un altro suggerimento della stessa guida che potrebbe essere utile è:

Quindi, ad esempio, se table_one un id colonna potresti aggiungere qualcosa come

and table_one.id between x and y

al where condizione ed eseguire la query più volte modificando i valori di x e y in modo che tutte le righe siano coperte.

Potresti voler fare attenzione quando usi ANALYZE opzione con EXPLAIN quando si tratta di dichiarazioni con effetti collaterali. Secondo la documentazione :