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.