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_id
ygood_id
para filtrar, los nuevos valores decitizen_id
y 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
possessions
partició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_id
ygood_id
, así como el número de filas. -
Unirse a
possessions
y el resultado de la unión anterior en los valores de clave principal y actualizarcitizen_id
con 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
.)