MySQL Update Join para Alterar Múltiplas Linhas de uma só vez

// explicit inner join
UPDATE product AS p
INNER JOIN product_price AS pp ON (pp.product_id = p.product_id)
SET pp.old_price = p.current_price,
    p.current_price = pp.base_price * 0.8
WHERE p.created_at < '2021-01-01';

// implicit inner join
UPDATE product AS p, product_price AS pp
SET pp.old_price = p.current_price,
    p.current_price = pp.base_price * 0.8
WHERE pp.product_id = p.product_id
p.created_at < '2021-01-01';

// explicit left join, only left side is updatable
UPDATE product AS p
LEFT JOIN product_price AS pp ON (pp.product_id = p.product_id)
SET p.deleted = 1
WHERE p.created_at < '2021-01-01';

Toda vez que eu estudo um banco de dados novo uma das coisas que sempre busco em todos eles é entender como escrever a sintaxe de um update em massa apenas relacionando tabelas sem a necessidade de laços for ou foreach bastante comuns em Stored Procedures. Esta preferência é porque a performance de uma instrução SQL é amplamente superior a execução de um laço de programação.

Eu peguei esta mania por que quando iniciei na linguagem SQL com banco de dados Informix, este banco de dados possuía uma sintaxe fora de serie para fazer update com dados entre tabelas. A sintaxe era bastante comum e intuitiva que permitia a alteração de diversas colunas e diversas linhas num mesmo comando.

Como o pessoal da MySQL AB também era fora de série eles implementaram uma funcionalidade chamada de Cross Table Update, que nada mais é que um update que permite join com outras tabelas. Resumindo, esta funcionalidade do MySQL preenche com perfeição o comportamento que eu conseguia executar com o Informix.

Outra forma de se fazer update em massa é utilizando-se sub-selects, porém as instruções do update com join são infinitamente mais simples de serem escritas e também a performance com o update join é bem melhor.

E para que não finquem dúvidas sobre a autoria deste recurso, esta funcionalidade foi disponibilizada desde a versão 4.0 do MySQL.

Uma salva de palma pra eles… genial!

Deixe um comentário