Ada beberapa cara untuk menyelesaikan masalah.
1. menambahkan kolom untuk sementara
Seperti yang disebutkan orang lain, cara langsungnya adalah menambahkan kolom reminder_id untuk sementara ke dateset . Isi dengan IDs asli dari reminder meja. Gunakan untuk bergabung dengan reminder dengan dateset meja. Jatuhkan kolom sementara.
2. ketika awalnya unik
Jika nilai start kolom unik, Anda dapat melakukannya tanpa kolom tambahan dengan bergabung dengan reminder tabel dengan dateset tabel di start kolom.
INSERT INTO dateset (start)
SELECT start FROM reminder;
WITH
CTE_Joined
AS
(
SELECT
reminder.id AS reminder_id
,reminder.dateset_id AS old_dateset_id
,dateset.id AS new_dateset_id
FROM
reminder
INNER JOIN dateset ON dateset.start = reminder.start
)
UPDATE CTE_Joined
SET old_dateset_id = new_dateset_id
;
3. saat awal tidak unik
Dimungkinkan untuk melakukannya tanpa kolom sementara bahkan dalam kasus ini. Ide utamanya adalah sebagai berikut. Mari kita lihat contoh ini:
Kami memiliki dua baris di reminder dengan start yang sama nilai dan ID 3 dan 7:
reminder
id start dateset_id
3 2015-01-01 NULL
7 2015-01-01 NULL
Setelah kita masukkan ke dalam dateset , akan ada ID baru yang dihasilkan, misalnya 1 dan 2:
dateset
id start
1 2015-01-01
2 2015-01-01
Tidak masalah bagaimana kita menghubungkan dua baris ini. Hasil akhirnya bisa
reminder
id start dateset_id
3 2015-01-01 1
7 2015-01-01 2
atau
reminder
id start dateset_id
3 2015-01-01 2
7 2015-01-01 1
Kedua varian ini benar. Yang membawa kita ke solusi berikut.
Cukup masukkan semua baris terlebih dahulu.
INSERT INTO dateset (start)
SELECT start FROM reminder;
Cocokkan/gabungkan dua tabel di start kolom mengetahui bahwa itu tidak unik. "Jadikan" unik dengan menambahkan ROW_NUMBER dan bergabung dengan dua kolom. Dimungkinkan untuk membuat kueri lebih pendek, tetapi saya mengeja setiap langkah secara eksplisit:
WITH
CTE_reminder_rn
AS
(
SELECT
id
,start
,dateset_id
,ROW_NUMBER() OVER (PARTITION BY start ORDER BY id) AS rn
FROM reminder
)
,CTE_dateset_rn
AS
(
SELECT
id
,start
,ROW_NUMBER() OVER (PARTITION BY start ORDER BY id) AS rn
FROM dateset
)
,CTE_Joined
AS
(
SELECT
CTE_reminder_rn.id AS reminder_id
,CTE_reminder_rn.dateset_id AS old_dateset_id
,CTE_dateset_rn.id AS new_dateset_id
FROM
CTE_reminder_rn
INNER JOIN CTE_dateset_rn ON
CTE_dateset_rn.start = CTE_reminder_rn.start AND
CTE_dateset_rn.rn = CTE_reminder_rn.rn
)
UPDATE CTE_Joined
SET old_dateset_id = new_dateset_id
;
Saya harap jelas dari kode apa fungsinya, terutama ketika Anda membandingkannya dengan versi yang lebih sederhana tanpa ROW_NUMBER . Jelas, solusi kompleks akan bekerja bahkan jika start unik, tetapi tidak seefisien solusi sederhana.
Solusi ini mengasumsikan bahwa dateset kosong sebelum proses ini.