Existem várias maneiras de resolver o problema.
1. adicionar temporariamente uma coluna
Como outros mencionaram, a maneira mais direta é adicionar temporariamente uma coluna
reminder_id
para o dateset
. Preencha-o com IDs
originais de reminder
tabela. Use-o para participar do reminder
com o dateset
tabela. Solte a coluna temporária. 2. quando o início é único
Se os valores do
start
coluna é única é possível fazê-lo sem coluna extra juntando reminder
tabela com o dateset
tabela no start
coluna. 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. quando o início não é exclusivo
É possível fazê-lo sem coluna temporária mesmo neste caso. A ideia principal é a seguinte. Vamos dar uma olhada neste exemplo:
Temos duas linhas em
reminder
com o mesmo start
valor e IDs 3 e 7:reminder
id start dateset_id
3 2015-01-01 NULL
7 2015-01-01 NULL
Depois de inseri-los no
dateset
, serão gerados novos IDs, por exemplo, 1 e 2:dateset
id start
1 2015-01-01
2 2015-01-01
Não importa realmente como vinculamos essas duas linhas. O resultado final pode ser
reminder
id start dateset_id
3 2015-01-01 1
7 2015-01-01 2
ou
reminder
id start dateset_id
3 2015-01-01 2
7 2015-01-01 1
Ambas as variantes estão corretas. O que nos leva à seguinte solução.
Basta inserir todas as linhas primeiro.
INSERT INTO dateset (start)
SELECT start FROM reminder;
Combine/junte duas tabelas em
start
coluna sabendo que ela não é única. "Torne-o" exclusivo adicionando ROW_NUMBER
e unindo por duas colunas. É possível tornar a consulta mais curta, mas expliquei cada etapa explicitamente: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
;
Espero que fique claro no código o que ele faz, especialmente quando você o compara com a versão mais simples sem
ROW_NUMBER
. Obviamente, a solução complexa funcionará mesmo se start
é único, mas não é tão eficiente, como uma solução simples. Esta solução assume que
dateset
está vazio antes deste processo.