O método a seguir depende do fato de que as
possessions tabela tem uma chave primária e citizen_id não faz parte. Aqui está a ideia:-
Coloque todos os parâmetros da atualização (citizen_idegood_idpara filtrar, os novos valores decitizen_ide o número de linhas a serem atualizadas) em algum armazenamento, uma tabela dedicada, talvez, ou uma tabela temporária.
-
Atribuir números de linha apossessionsparticionamento de linhas em(citizen_id, good_id), junte o conjunto de linhas classificadas à tabela de parâmetros para filtrar o conjunto completo original emcitizen_idegood_id, bem como o número de linhas.
-
Junte-se apossessionse o resultado da junção anterior nos valores da chave primária e atualizecitizen_idcom os novos valores.
No SQL do MySQL, o acima pode ficar assim:
UPDATE possessions AS p
INNER JOIN
(
SELECT
@r := @r * (@c = p.citizen_id AND @g = p.good_id) + 1 AS r,
p.possession_id,
@c := p.citizen_id AS citizen_id,
@g := p.good_id AS good_id
FROM
possessions AS p
CROSS JOIN
(SELECT @r := 0, @c := 0, @g := 0) AS x
ORDER BY
p.citizen_id,
p.good_id
) AS f ON p.possession_id = f.possession_id
INNER JOIN
possession_updates AS u ON u.citizen_id = f.citizen_id AND u.good_id = f.good_id
SET
p.citizen_id = u.new_citizen_id
WHERE
f.r <= u.row_count
;
O
possessions_update é a tabela que contém os valores dos parâmetros. A consulta usa um método conhecido de numeração de linha que emprega variáveis, que é implementada no
f subconsulta. Eu não tenho MySQL, então não posso testar isso corretamente do ponto de vista do desempenho, mas pelo menos você pode ver em esta demonstração do SQL Fiddle que o método funciona. (A instrução UPDATE está no script de esquema, porque o SQL Fiddle não permite instruções de modificação de dados no script do lado direito do MySQL. O lado direito apenas retorna o conteúdo pós-UPDATE de
possessions .)