Esistono diversi modi per risolvere il problema.
Come altri hanno già detto, il modo più semplice è aggiungere temporaneamente una colonna reminder_id
al dateset
. Completalo con gli IDs
originali da reminder
tavolo. Usalo per unirti a reminder
con il dateset
tavolo. Rilascia la colonna temporanea.
Se i valori di start
colonna è unica è possibile farlo senza colonna aggiuntiva unendo reminder
tabella con il dateset
tabella su start
colonna.
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
;
È possibile farlo senza colonna temporanea anche in questo caso. L'idea principale è la seguente. Diamo un'occhiata a questo esempio:
Abbiamo due righe in reminder
con lo stesso start
valore e ID 3 e 7:
reminder
id start dateset_id
3 2015-01-01 NULL
7 2015-01-01 NULL
Dopo averli inseriti nel dateset
, verranno generati nuovi ID, ad esempio 1 e 2:
dateset
id start
1 2015-01-01
2 2015-01-01
Non importa come colleghiamo queste due righe. Il risultato finale potrebbe essere
reminder
id start dateset_id
3 2015-01-01 1
7 2015-01-01 2
o
reminder
id start dateset_id
3 2015-01-01 2
7 2015-01-01 1
Entrambe queste varianti sono corrette. Il che ci porta alla seguente soluzione.
Basta inserire prima tutte le righe.
INSERT INTO dateset (start)
SELECT start FROM reminder;
Abbina/unisci due tabelle su start
colonna sapendo che non è unico. "Rendilo" unico aggiungendo ROW_NUMBER
e uniti da due colonne. È possibile abbreviare la query, ma ho esplicitato ogni passaggio in modo esplicito:
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
;
Spero che sia chiaro dal codice cosa fa, soprattutto quando lo confronti con la versione più semplice senza ROW_NUMBER
. Ovviamente, la soluzione complessa funzionerà anche se start
è unico, ma non è efficiente come una soluzione semplice.
Questa soluzione presuppone che dateset
è vuoto prima di questo processo.