Следният метод разчита на факта, че possessions таблицата има първичен ключ и citizen_id не е част от него. Ето идеята:
-
Поставете всички параметри на актуализацията (
citizen_idиgood_idза филтриране, новите стойности наcitizen_idи броя на редовете за актуализиране) в някакво хранилище, специална таблица, може би, или временна таблица. -
Присвояване на номера на редове към
possessionsразделяне на редове на(citizen_id, good_id), след това присъединете класирания набор от редове към таблицата с параметри, за да филтрирате оригиналния пълен набор наcitizen_idиgood_id, както и броя на редовете. -
Присъединете се към
possessionsи резултата от предишното присъединяване към стойностите на първичния ключ и актуализиране наcitizen_idс новите стойности.
В SQL на MySQL горното може да изглежда така:
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
;
possessions_update е таблицата, съдържаща стойностите на параметрите.
Заявката използва известен метод за номериране на редове, който използва променливи, който е имплементиран в f подзаявка.
Нямам MySQL, така че не мога да тествам това правилно от гледна точка на производителността, но поне можете да видите от тази демонстрация на SQL Fiddle
че методът работи. (Инструкцията UPDATE е в скрипта на схемата, тъй като SQL Fiddle не позволява инструкции за модифициране на данни в скрипта от дясната страна за MySQL. Дясната страна просто връща съдържанието след АКТУАЛИЗАЦИЯ на possessions .)