PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Instrução de atualização usando uma cláusula WHERE que contém colunas com valores nulos


Como null = null avalia como false você precisa verificar se dois campos são ambos null além da verificação de igualdade:
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

Você também pode usar o coalesce função que é mais legível:
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

Mas você precisa ter cuidado com os valores padrão (último argumento para coalesce ).
Seu tipo de dados deve corresponder ao tipo de coluna (para que você não acabe comparando datas com números, por exemplo) e o padrão deve ser tal que não apareça nos dados
E.g coalesce(null, 1) = coalesce(1, 1) é uma situação que você gostaria de evitar.

Atualização (em relação ao desempenho):


Seq Scan on table_two - isso sugere que você não tem nenhum índice em table_two .
Então, se você atualizar uma linha em table_one em seguida, para encontrar uma linha correspondente em table_two o banco de dados basicamente tem que varrer todas as linhas uma a uma até encontrar uma correspondência.
As linhas correspondentes poderiam ser encontradas muito mais rapidamente se as colunas relevantes fossem indexadas.

Por outro lado, se table_one tem algum índice que retarda a atualização.
De acordo com este guia de desempenho :

Outra sugestão do mesmo guia que pode ser útil é:

Por exemplo, se table_one um id coluna você pode adicionar algo como
and table_one.id between x and y

para o where condição e execute a consulta várias vezes alterando os valores de x e y para que todas as linhas sejam cobertas.

Você pode querer ter cuidado ao usar o ANALYZE opção com EXPLAIN ao lidar com declarações com efeitos colaterais. De acordo com a documentação :