Följande metod bygger på det faktum att possessions
tabellen har en primärnyckel och citizen_id
är inte en del av det. Här är idén:
-
Ange alla parametrar för uppdateringen (
citizen_id
ochgood_id
att filtrera på, de nya värdena förcitizen_id
och antalet rader som ska uppdateras) till någon lagring, en dedikerad tabell, kanske, eller en tillfällig tabell. -
Tilldela radnummer till
possessions
radpartitionering på(citizen_id, good_id)
, anslut sedan den rankade raduppsättningen till parametertabellen för att filtrera den ursprungliga fullständiga uppsättningen påcitizen_id
ochgood_id
, samt antalet rader. -
Gå med i
possessions
och resultatet av den föregående kopplingen på primärnyckelvärdena och uppdateracitizen_id
med de nya värdena.
I MySQL:s SQL kan ovanstående se ut så här:
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
är tabellen som innehåller parametervärdena.
Frågan använder en känd metod för radnumrering som använder variabler, som är implementerad i f
underfråga.
Jag har inte MySQL så jag kan inte testa detta ordentligt ur prestandasynpunkt, men du kan åtminstone se från denna SQL Fiddle-demo
att metoden fungerar. (UPDATE-satsen finns i schemaskriptet, eftersom SQL Fiddle inte tillåter datamodifieringssatser i skriptet på höger sida för MySQL. Den högra sidan returnerar bara innehållet efter UPDATE i possessions
.)