Die folgende Methode beruht auf der Tatsache, dass die possessions Tabelle hat einen Primärschlüssel und citizen_id gehört nicht dazu. Hier ist die Idee:
-
Setzen Sie alle Parameter des Updates (
citizen_idundgood_idzum Filtern, die neuen Werte voncitizen_idund die Anzahl der zu aktualisierenden Zeilen) in einen Speicher, vielleicht eine dedizierte Tabelle oder eine temporäre Tabelle. -
Ordnen Sie
possessionsZeilennummern zu Zeilenpartitionierung auf(citizen_id, good_id), und verbinden Sie dann den geordneten Zeilensatz mit der Parametertabelle, um den ursprünglichen vollständigen Satz nachcitizen_idzu filtern undgood_id, sowie die Anzahl der Zeilen. -
Tritt
possessionsbei und das Ergebnis der vorherigen Verknüpfung der Primärschlüsselwerte und aktualisieren Siecitizen_idmit den neuen Werten.
In SQL von MySQL könnte das Obige so aussehen:
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
;
Das possessions_update ist die Tabelle mit den Parameterwerten.
Die Abfrage verwendet eine bekannte Methode der Zeilennummerierung, die Variablen verwendet, die in f implementiert ist Unterabfrage.
Ich habe kein MySQL, also kann ich das aus Performance-Sicht nicht richtig testen, aber zumindest können Sie von diese SQL Fiddle-Demo
dass die Methode funktioniert. (Die UPDATE-Anweisung befindet sich im Schemaskript, da SQL Fiddle keine Datenänderungsanweisungen im rechten Skript für MySQL zulässt. Die rechte Seite gibt nur den Post-UPDATE-Inhalt von possessions zurück .)