Có một số cách để giải quyết vấn đề.
1. tạm thời thêm một cột
Như những người khác đã đề cập, cách đơn giản là thêm tạm thời một cột reminder_id
đến dateset
. Điền nó với IDs
ban đầu từ reminder
bàn. Sử dụng nó để tham gia reminder
với dateset
bàn. Bỏ cột tạm thời.
2. khi bắt đầu là duy nhất
Nếu các giá trị của start
cột là duy nhất, bạn có thể thực hiện điều đó mà không cần thêm cột bằng cách tham gia reminder
bảng với dateset
trên start
cột.
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. khi bắt đầu không phải là duy nhất
Có thể làm điều đó mà không cần cột tạm thời ngay cả trong trường hợp này. Ý tưởng chính là sau đây. Hãy xem ví dụ này:
Chúng tôi có hai hàng trong reminder
với cùng một start
giá trị và ID 3 và 7:
reminder
id start dateset_id
3 2015-01-01 NULL
7 2015-01-01 NULL
Sau khi chúng tôi chèn chúng vào dateset
, sẽ có các ID mới được tạo, ví dụ:1 và 2:
dateset
id start
1 2015-01-01
2 2015-01-01
Không thực sự quan trọng bằng cách nào chúng ta liên kết hai hàng này. Kết quả cuối cùng có thể là
reminder
id start dateset_id
3 2015-01-01 1
7 2015-01-01 2
hoặc
reminder
id start dateset_id
3 2015-01-01 2
7 2015-01-01 1
Cả hai biến thể này đều đúng. Điều này đưa chúng ta đến giải pháp sau.
Chỉ cần chèn tất cả các hàng trước.
INSERT INTO dateset (start)
SELECT start FROM reminder;
Khớp / nối hai bảng trên start
cột biết rằng nó không phải là duy nhất. "Làm cho nó" trở thành duy nhất bằng cách thêm ROW_NUMBER
và nối bằng hai cột. Có thể làm cho truy vấn ngắn hơn, nhưng tôi đã viết rõ ràng từng bước:
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
;
Tôi hy vọng nó rõ ràng từ mã những gì nó làm, đặc biệt là khi bạn so sánh nó với phiên bản đơn giản hơn mà không có ROW_NUMBER
. Rõ ràng, giải pháp phức tạp sẽ hoạt động ngay cả khi start
là duy nhất, nhưng nó không hiệu quả như một giải pháp đơn giản.
Giải pháp này giả định rằng dateset
trống trước quá trình này.