Metode berikut bergantung pada fakta bahwa possessions
tabel memiliki kunci utama dan citizen_id
bukan bagian darinya. Inilah idenya:
-
Masukkan semua parameter pembaruan (
citizen_id
dangood_id
untuk memfilter, nilai barucitizen_id
dan jumlah baris yang akan diperbarui) ke dalam beberapa penyimpanan, tabel khusus, mungkin, atau tabel sementara. -
Tetapkan nomor baris ke
possessions
partisi baris pada(citizen_id, good_id)
, lalu gabungkan kumpulan baris peringkat ke tabel parameter untuk memfilter kumpulan lengkap asli dicitizen_id
dangood_id
, serta jumlah baris. -
Bergabunglah dengan
possessions
dan hasil join sebelumnya pada nilai primary key dan updatecitizen_id
dengan nilai-nilai baru.
Dalam SQL MySQL, di atas mungkin terlihat seperti ini:
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
adalah tabel yang berisi nilai parameter.
Kueri menggunakan metode penomoran baris yang diketahui yang menggunakan variabel, yang diimplementasikan di f
subkueri.
Saya tidak memiliki MySQL jadi saya tidak dapat menguji ini dengan benar dari sudut pandang kinerja, tetapi setidaknya Anda dapat melihat dari demo SQL Fiddle ini
bahwa metode itu berhasil. (Pernyataan UPDATE ada di skrip skema, karena SQL Fiddle tidak mengizinkan pernyataan modifikasi data di skrip sisi kanan untuk MySQL. Sisi kanan hanya mengembalikan konten possessions
pasca-UPDATE .)