El siguiente método se basa en el hecho de que las possessions la tabla tiene una clave principal y citizen_id no es parte de eso. Esta es la idea:
-
Ponga todos los parámetros de la actualización (
citizen_idygood_idpara filtrar, los nuevos valores decitizen_idy el número de filas para actualizar) en algún almacenamiento, una tabla dedicada, tal vez, o una tabla temporal. -
Asigne números de fila a
possessionspartición de filas en(citizen_id, good_id), luego una el conjunto de filas clasificadas a la tabla de parámetros para filtrar el conjunto completo original encitizen_idygood_id, así como el número de filas. -
Unirse a
possessionsy el resultado de la unión anterior en los valores de clave principal y actualizarcitizen_idcon los nuevos valores.
En SQL de MySQL, lo anterior podría verse así:
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
;
La possessions_update es la tabla que contiene los valores de los parámetros.
La consulta utiliza un método conocido de numeración de filas que emplea variables, que se implementa en el f subconsulta.
No tengo MySQL, así que no puedo probar esto correctamente desde el punto de vista del rendimiento, pero al menos puedes ver desde esta demostración de SQL Fiddle
que el método funciona. (La instrucción UPDATE está en el script del esquema, porque SQL Fiddle no permite declaraciones de modificación de datos en el script del lado derecho para MySQL. El lado derecho solo devuelve el contenido posterior a la ACTUALIZACIÓN de possessions .)