Има няколко начина за решаване на проблема.
1. временно добавяне на колоната
Както други споменаха, директният начин е временно да добавите колона reminder_id
към dateset
. Попълнете го с оригинални IDs
от reminder
маса. Използвайте го, за да се присъедините към reminder
с dateset
маса. Пуснете временната колона.
2. когато стартът е уникален
Ако стойностите на start
колоната е уникална, възможно е да го направите без допълнителна колона, като се присъедините към reminder
таблица с dateset
таблица в start
колона.
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. когато стартът не е уникален
Възможно е дори в този случай да се направи без временна колона. Основната идея е следната. Нека да разгледаме този пример:
Имаме два реда в reminder
със същия start
стойност и идентификатори 3 и 7:
reminder
id start dateset_id
3 2015-01-01 NULL
7 2015-01-01 NULL
След като ги вмъкнем в dateset
, ще бъдат генерирани нови идентификатори, например 1 и 2:
dateset
id start
1 2015-01-01
2 2015-01-01
Всъщност няма значение как свързваме тези два реда. Крайният резултат може да бъде
reminder
id start dateset_id
3 2015-01-01 1
7 2015-01-01 2
или
reminder
id start dateset_id
3 2015-01-01 2
7 2015-01-01 1
И двата варианта са верни. Което ни води до следното решение.
Просто първо вмъкнете всички редове.
INSERT INTO dateset (start)
SELECT start FROM reminder;
Сравнете/съединете две таблици при start
колона, знаейки, че не е уникална. „Направете го“ уникален, като добавите ROW_NUMBER
и съединяване с две колони. Възможно е заявката да бъде по-кратка, но изрично описах всяка стъпка:
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
;
Надявам се, че от кода става ясно какво прави, особено когато го сравнявате с по-простата версия без ROW_NUMBER
. Очевидно сложното решение ще работи дори ако start
е уникален, но не е толкова ефективен, колкото просто решение.
Това решение предполага, че dateset
е празен преди този процес.