Es gibt mehrere Möglichkeiten, das Problem zu lösen.
1. vorübergehend eine Spalte hinzufügen
Wie bereits erwähnt, ist der direkte Weg, vorübergehend eine Spalte reminder_id
hinzuzufügen zum dateset
. Füllen Sie es mit den ursprünglichen IDs
von reminder
Tisch. Verwenden Sie es, um reminder
beizutreten mit dem dateset
Tisch. Löschen Sie die temporäre Spalte.
2. wenn start eindeutig ist
Wenn Werte von start
Spalte einzigartig ist, ist es möglich, sie ohne zusätzliche Spalte zu machen, indem man reminder
hinzufügt Tabelle mit dem dateset
Tabelle am start
Spalte.
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. wenn start nicht eindeutig ist
Auch in diesem Fall ist es möglich, auf eine temporäre Spalte zu verzichten. Die Hauptidee ist die folgende. Schauen wir uns dieses Beispiel an:
Wir haben zwei Zeilen in reminder
mit demselben start
Wert und IDs 3 und 7:
reminder
id start dateset_id
3 2015-01-01 NULL
7 2015-01-01 NULL
Nachdem wir sie in das dateset
eingefügt haben , werden neue IDs generiert, zum Beispiel 1 und 2:
dateset
id start
1 2015-01-01
2 2015-01-01
Es spielt keine Rolle, wie wir diese beiden Zeilen verknüpfen. Das Endergebnis könnte
seinreminder
id start dateset_id
3 2015-01-01 1
7 2015-01-01 2
oder
reminder
id start dateset_id
3 2015-01-01 2
7 2015-01-01 1
Beide Varianten sind richtig. Das bringt uns zu folgender Lösung.
Einfach alle Zeilen zuerst einfügen.
INSERT INTO dateset (start)
SELECT start FROM reminder;
Ordnen Sie zwei Tische bei start
zu/verbinden Sie sie Spalte in dem Wissen, dass sie nicht eindeutig ist. "Machen Sie es" einzigartig, indem Sie ROW_NUMBER
hinzufügen und Verbinden durch zwei Spalten. Es ist möglich, die Abfrage zu verkürzen, aber ich habe jeden Schritt explizit aufgeführt:
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
;
Ich hoffe, es ist aus dem Code ersichtlich, was er tut, besonders wenn man ihn mit der einfacheren Version ohne ROW_NUMBER
vergleicht . Offensichtlich funktioniert die komplexe Lösung auch, wenn start
ist einzigartig, aber nicht so effizient wie eine einfache Lösung.
Diese Lösung geht davon aus, dass dateset
ist vor diesem Vorgang leer.