實務上常需在同一張表內,依據某欄位模式匹配,將符合條件的記錄以另一筆記錄的資料覆蓋更新。本文實例展示如何處理 metadata_xt 表中 me_title 為 '第__講 精簡版' 的記錄,找出同組(other_courseware_name 相同)且標題前綴相符的「源記錄」,同步更新欄位並重組標題。
metadata_xt(id, subject_id, other_courseware_name, me_author, me_title, me_key, me_abstract)
-- id 唯一,me_title 應唯一但無約束(可能重複,重複時其他欄位必定相同視為冗餘)
匹配模式:
me_title LIKE '第__講 精簡版'(雙位數講次)me_title LIKE '第%' 且 不含 '精簡版''第01講'、'第55講'),或源記錄為單位數格式 '第_講%' 時,比對第 3 字元為 '0' 且第 4-6 字元相符先更新非關鍵欄位,再更新關鍵欄位 me_title,避免匹配條件失效。
UPDATE DB2ADMIN.metadata_xt AS a
SET (me_key, me_abstract, subject_id, me_author) =
(SELECT DISTINCT me_key, me_abstract, subject_id, me_author
FROM DB2ADMIN.metadata_xt AS b
WHERE other_courseware_name = '房屋建築學'
AND b.me_title LIKE '第%'
AND ( LEFT(b.me_title, 6) = LEFT(a.me_title, 6)
OR ( SUBSTR(a.me_title, 3, 1) = '0'
AND SUBSTR(a.me_title, 4, 3) = SUBSTR(b.me_title, 3, 3) )
)
AND b.me_title <> a.me_title)
WHERE other_courseware_name = '房屋建築學'
AND me_title LIKE '第__講 精簡版'
AND EXISTS (
SELECT 1 FROM DB2ADMIN.metadata_xt AS c
WHERE c.other_courseware_name = '房屋建築學'
AND c.me_title LIKE '第%'
AND ( LEFT(c.me_title, 6) = LEFT(a.me_title, 6)
OR ( SUBSTR(a.me_title, 3, 1) = '0'
AND SUBSTR(a.me_title, 4, 3) = SUBSTR(c.me_title, 3, 3) )
)
AND c.me_title <> a.me_title
);
關鍵技巧:
SET (col1, col2, ...) = (SELECT ...):DB2 支援單一子查詢同時賦值多欄位DISTINCT 確保子查詢只回傳單列,避免「單列子查詢回傳多列」錯誤EXISTS 子句:防止無匹配源記錄時將目標欄位設為 NULLLEFT()、SUBSTR() 組合實現彈性前綴匹配UPDATE DB2ADMIN.metadata_xt AS a
SET me_title =
(SELECT DISTINCT me_title
FROM DB2ADMIN.metadata_xt AS b
WHERE other_courseware_name = '房屋建築學'
AND b.me_title LIKE '第%'
AND ( LEFT(b.me_title, 6) = LEFT(a.me_title, 6)
OR ( SUBSTR(a.me_title, 3, 1) = '0'
AND SUBSTR(a.me_title, 4, 3) = SUBSTR(b.me_title, 3, 3) )
)
AND b.me_title <> a.me_title) || ' (精簡版)'
WHERE other_courseware_name = '房屋建築學'
AND me_title LIKE '第__講 精簡版'
AND EXISTS (
SELECT 1 FROM DB2ADMIN.metadata_xt AS c
WHERE c.other_courseware_name = '房屋建築學'
AND c.me_title LIKE '第%'
AND ( LEFT(c.me_title, 6) = LEFT(a.me_title, 6)
OR ( SUBSTR(a.me_title, 3, 1) = '0'
AND SUBSTR(a.me_title, 4, 3) = SUBSTR(c.me_title, 3, 3) )
)
AND c.me_title <> a.me_title
);
更新後 me_title = 源記錄標題 + ' (精簡版)',其他欄位同步為源記錄值。
me_title 導致第二階段匹配失敗EXISTS 保護,否則無匹配源記錄時會寫入 NULLDISTINCT 配合 b.me_title <> a.me_title 確保不自我匹配且唯一FETCH FIRST N ROWS ONLY)避免長鎖定