表 org_info 按 ID 分組,需將每組 OCCUR_DATE 最早的一條記錄的 OP_TYPE 更新為 1。嘗試使用子查詢更新報錯 ORA-01732。
Oracle 不允許直接更新包含分析函數(如 ROW_NUMBER())的內聯視圖/子查詢,因其被視為「非鍵保留表」,無法確定唯一行對應關係。
UPDATE org_info
SET op_type = 1
WHERE rowid IN (
SELECT rid
FROM (
SELECT rowid AS rid,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY occur_date ASC) AS rn
FROM org_info
)
WHERE rn = 1
);
rn=1 獲取目標 ROWID 集合。MERGE INTO org_info t
USING (
SELECT rowid AS rid,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY occur_date ASC) AS rn
FROM org_info
) s
ON (t.rowid = s.rid AND s.rn = 1)
WHEN MATCHED THEN UPDATE SET t.op_type = 1;
MERGE 語義更清晰,支持複雜條件,大數據量時性能可通過並行提示優化:/*+ PARALLEL(4) */。
ID、OCCUR_DATE 有索引,加速分組排序。WHERE rowid IN (SELECT ... WHERE rownum <= 10000) 循環提交。SELECT id, occur_date, op_type
FROM org_info
ORDER BY id, occur_date;
確認每組第一條 op_type=1,其餘為原值或 0。
掌握 ROWID 更新模式,是 Oracle DBA/開發處理「分組 Top-N 更新」的必備技能。