Det finns flera sätt att lösa problemet.
1. tillfälligt lägga till en kolumn
Som andra nämnt är det enkla sättet att tillfälligt lägga till en kolumn reminder_id
till dateset
. Fyll den med original IDs
från reminder
tabell. Använd den för att gå med i reminder
med dateset
tabell. Släpp den tillfälliga kolumnen.
2. när start är unik
Om värden för start
kolumnen är unik det är möjligt att göra det utan extra kolumn genom att gå med i reminder
tabell med dateset
tabellen på start
kolumn.
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. när start inte är unik
Det är möjligt att göra det utan tillfällig kolumn även i detta fall. Huvudtanken är följande. Låt oss ta en titt på detta exempel:
Vi har två rader i reminder
med samma start
värde och ID 3 och 7:
reminder
id start dateset_id
3 2015-01-01 NULL
7 2015-01-01 NULL
Efter att vi har infogat dem i dateset
, kommer det att skapas nya ID, till exempel 1 och 2:
dateset
id start
1 2015-01-01
2 2015-01-01
Det spelar egentligen ingen roll hur vi länkar dessa två rader. Slutresultatet kan bli
reminder
id start dateset_id
3 2015-01-01 1
7 2015-01-01 2
eller
reminder
id start dateset_id
3 2015-01-01 2
7 2015-01-01 1
Båda dessa varianter är korrekta. Vilket leder oss till följande lösning.
Sätt bara in alla rader först.
INSERT INTO dateset (start)
SELECT start FROM reminder;
Matcha/ansluta två bord på start
kolumn vet att det inte är unikt. "Gör det" unikt genom att lägga till ROW_NUMBER
och sammanfogning med två kolumner. Det är möjligt att göra frågan kortare, men jag stavade uttryckligen varje steg:
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
;
Jag hoppas att det framgår av koden vad den gör, särskilt när du jämför den med den enklare versionen utan ROW_NUMBER
. Uppenbarligen kommer den komplexa lösningen att fungera även om start
är unik, men den är inte lika effektiv som en enkel lösning.
Denna lösning förutsätter att dateset
är tom före denna process.