Istnieje kilka sposobów rozwiązania tego problemu.
1. tymczasowo dodaj kolumnę
Jak wspomnieli inni, najprostszym sposobem jest tymczasowe dodanie kolumny reminder_id
do dateset
. Wypełnij go oryginalnymi IDs
z reminder
stół. Użyj go, aby dołączyć do reminder
z dateset
stół. Upuść kolumnę tymczasową.
2. kiedy start jest wyjątkowy
Jeśli wartości start
kolumna jest unikalna, można to zrobić bez dodatkowej kolumny, łącząc reminder
tabela z dateset
tabela na start
kolumna.
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. kiedy start nie jest wyjątkowy
Nawet w tym przypadku można to zrobić bez kolumny tymczasowej. Główna idea jest następująca. Spójrzmy na ten przykład:
Mamy dwa wiersze w reminder
z tym samym start
wartość i identyfikatory 3 i 7:
reminder
id start dateset_id
3 2015-01-01 NULL
7 2015-01-01 NULL
Po wstawieniu ich do dateset
, zostaną wygenerowane nowe identyfikatory, na przykład 1 i 2:
dateset
id start
1 2015-01-01
2 2015-01-01
Tak naprawdę nie ma znaczenia, jak połączymy te dwa wiersze. Efektem końcowym może być
reminder
id start dateset_id
3 2015-01-01 1
7 2015-01-01 2
lub
reminder
id start dateset_id
3 2015-01-01 2
7 2015-01-01 1
Oba te warianty są poprawne. Co prowadzi nas do następującego rozwiązania.
Po prostu wstaw najpierw wszystkie wiersze.
INSERT INTO dateset (start)
SELECT start FROM reminder;
Dopasuj/dołącz do dwóch stołów na start
kolumna wiedząc, że nie jest unikalna. „Uczyń to” unikalnym, dodając ROW_NUMBER
i łączenie dwiema kolumnami. Możliwe jest skrócenie zapytania, ale każdy krok wyraźnie opisałem:
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
;
Mam nadzieję, że z kodu jasno wynika, co robi, zwłaszcza gdy porównasz ją z prostszą wersją bez ROW_NUMBER
. Oczywiście złożone rozwiązanie będzie działać, nawet jeśli start
jest wyjątkowy, ale nie jest tak wydajny, jak proste rozwiązanie.
To rozwiązanie zakłada, że dateset
jest pusty przed tym procesem.