समस्या को हल करने के कई तरीके हैं।
<मजबूत>1. अस्थायी रूप से एक कॉलम जोड़ें
जैसा कि अन्य ने उल्लेख किया है, सीधा-आगे तरीका अस्थायी रूप से एक कॉलम जोड़ना है reminder_id
dateset
. तक . इसे मूल IDs
with से भरें 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
. में दो पंक्तियाँ हैं उसी के साथ start
मान और आईडी 3 और 7:
reminder
id start dateset_id
3 2015-01-01 NULL
7 2015-01-01 NULL
हम उन्हें dateset
. में डालने के बाद , नई आईडी उत्पन्न होंगी, उदाहरण के लिए, 1 और 2:
dateset
id start
1 2015-01-01
2 2015-01-01
इससे कोई फर्क नहीं पड़ता कि हम इन दो पंक्तियों को कैसे जोड़ते हैं। अंतिम परिणाम हो सकता है
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
on पर दो तालिकाओं का मिलान/जुड़ें कॉलम यह जानते हुए कि यह अद्वितीय नहीं है। ROW_NUMBER
. जोड़कर "इसे अद्वितीय बनाएं" और दो कॉलम से जुड़ना। क्वेरी को छोटा करना संभव है, लेकिन मैंने प्रत्येक चरण को स्पष्ट रूप से लिखा है:
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
इस प्रक्रिया से पहले खाली है।