問題を解決するにはいくつかの方法があります。
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
このプロセスの前は空です。