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_id
undgood_id
zum Filtern, die neuen Werte voncitizen_id
und die Anzahl der zu aktualisierenden Zeilen) in einen Speicher, vielleicht eine dedizierte Tabelle oder eine temporäre Tabelle. -
Ordnen Sie
possessions
Zeilennummern 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_id
zu filtern undgood_id
, sowie die Anzahl der Zeilen. -
Tritt
possessions
bei und das Ergebnis der vorherigen Verknüpfung der Primärschlüsselwerte und aktualisieren Siecitizen_id
mit 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 .)