Existuje několik způsobů, jak problém vyřešit.
1. dočasně přidat sloupec
Jak již zmínili ostatní, přímým způsobem je dočasné přidání sloupce reminder_id
na dateset
. Naplňte jej původními IDs
z reminder
stůl. Použijte jej k připojení k reminder
s dateset
stůl. Zrušte dočasný sloupec.
2. kdy je start jedinečný
If hodnoty start
sloupec je jedinečný, lze to provést bez dalšího sloupce spojením reminder
tabulka s dateset
tabulky na start
sloupec.
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. kdy start není jedinečný
I v tomto případě to lze provést bez dočasného sloupce. Hlavní myšlenka je následující. Podívejme se na tento příklad:
V reminder
máme dva řádky se stejným start
hodnota a ID 3 a 7:
reminder
id start dateset_id
3 2015-01-01 NULL
7 2015-01-01 NULL
Poté, co je vložíme do dateset
, budou vygenerována nová ID, například 1 a 2:
dateset
id start
1 2015-01-01
2 2015-01-01
Nezáleží na tom, jak tyto dva řádky propojíme. Konečný výsledek by mohl být
reminder
id start dateset_id
3 2015-01-01 1
7 2015-01-01 2
nebo
reminder
id start dateset_id
3 2015-01-01 2
7 2015-01-01 1
Obě tyto varianty jsou správné. Což nás přivádí k následujícímu řešení.
Jednoduše nejprve vložte všechny řádky.
INSERT INTO dateset (start)
SELECT start FROM reminder;
Spojte/spojte dva stoly na start
sloupec s vědomím, že není jedinečný. „Udělejte to“ jedinečným přidáním ROW_NUMBER
a spojení dvěma sloupci. Dotaz je možné zkrátit, ale každý krok jsem výslovně uvedl:
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
;
Doufám, že z kódu je jasné, co dělá, zvláště když to porovnáte s jednodušší verzí bez ROW_NUMBER
. Je zřejmé, že komplexní řešení bude fungovat, i když start
je unikátní, ale není tak efektivní jako jednoduché řešení.
Toto řešení předpokládá, že dateset
je před tímto procesem prázdný.