問題を解決するにはいくつかの方法があります。
1。一時的に列を追加する
他の人が述べたように、簡単な方法は一時的に列reminder_idを追加することです datesetに 。元のIDsを入力します reminderから テーブル。 reminderに参加するために使用します datesetを使用 テーブル。一時列を削除します。
2。開始が一意の場合
startの値が 列は一意であり、reminderを結合することで余分な列なしでそれを行うことができます datesetのテーブル startのテーブル 列。
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。開始が一意でない場合
この場合でも、一時的な列がなくても実行できます。主なアイデアは次のとおりです。この例を見てみましょう:
reminderには2つの行があります 同じstartで 値とID3および7:
reminder
id start dateset_id
3 2015-01-01 NULL
7 2015-01-01 NULL
それらをdatesetに挿入した後 、たとえば1と2などの新しいIDが生成されます。
dateset
id start
1 2015-01-01
2 2015-01-01
これらの2つの行をどのようにリンクするかは実際には重要ではありません。最終結果は
になる可能性がありますreminder
id start dateset_id
3 2015-01-01 1
7 2015-01-01 2
または
reminder
id start dateset_id
3 2015-01-01 2
7 2015-01-01 1
これらのバリアントは両方とも正しいです。これにより、次の解決策が得られます。
最初にすべての行を挿入するだけです。
INSERT INTO dateset (start)
SELECT start FROM reminder;
startで2つのテーブルを一致/結合します それが一意ではないことを知っている列。 ROW_NUMBERを追加して、「Makeit」を一意にします 2列で結合します。クエリを短くすることは可能ですが、各ステップを明示的に説明しました:
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
;
特にROW_NUMBERのない単純なバージョンと比較すると、コードが何をするのかが明確になっていることを願っています。 。明らかに、startであっても、複雑なソリューションは機能します はユニークですが、単純なソリューションほど効率的ではありません。
このソリューションは、dateset このプロセスの前は空です。