Следният метод разчита на факта, че 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
.)