Der er flere måder at løse problemet på.
1. midlertidigt tilføje en kolonne
Som andre nævnte, er den enkle måde midlertidigt at tilføje en kolonne reminder_id
til dateset
. Udfyld den med originale IDs
fra reminder
bord. Brug den til at deltage i reminder
med dateset
bord. Slip den midlertidige kolonne.
2. når start er unik
Hvis værdierne for start
kolonne er unik, det er muligt at gøre det uden ekstra kolonne ved at deltage i reminder
tabel med dateset
tabel på start
kolonne.
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 ikke er unik
Det er muligt at gøre det uden midlertidig kolonne selv i dette tilfælde. Hovedideen er følgende. Lad os se på dette eksempel:
Vi har to rækker i reminder
med den samme start
værdi og ID'er 3 og 7:
reminder
id start dateset_id
3 2015-01-01 NULL
7 2015-01-01 NULL
Efter vi har indsat dem i dateset
, vil der blive genereret nye ID'er, f.eks. 1 og 2:
dateset
id start
1 2015-01-01
2 2015-01-01
Det er lige meget, hvordan vi forbinder disse to rækker. Slutresultatet kunne være
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
Begge disse varianter er korrekte. Hvilket bringer os til følgende løsning.
Indsæt blot alle rækker først.
INSERT INTO dateset (start)
SELECT start FROM reminder;
Match/forbind to borde på start
kolonne vel vidende, at det ikke er unikt. "Gør det" unikt ved at tilføje ROW_NUMBER
og forbindes med to søjler. Det er muligt at gøre forespørgslen kortere, men jeg har præciseret hvert trin eksplicit:
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
;
Jeg håber, det fremgår tydeligt af koden, hvad den gør, især når du sammenligner den med den enklere version uden ROW_NUMBER
. Det er klart, at den komplekse løsning virker, selvom start
er unik, men den er ikke så effektiv som en simpel løsning.
Denne løsning antager, at dateset
er tom før denne proces.