Oracle中使用Merge合并OBJID重复记录的方案咨询
解决Oracle表USEROPENNIS重复OBJID记录合并问题
针对你的需求(同一OBJID的两条记录合并,保留各列非空值),完全可以用MERGE语句高效实现,无需手动循环。以下提供两种可行方案:
方案一:直接MERGE更新+删除重复记录
这个方案直接在原表上操作,先把DUP=2记录的非空值补充到DUP=1的记录中,再删除重复的DUP=2记录。
1. 用MERGE补全空列
MERGE INTO USEROPENNIS tgt USING ( SELECT objid, INVKLASSE, NETTTYPE, NAVN, ALT_NAVN, ON_ID, ON_TYPE, ON_STED_NR, ON_OVER_ID FROM ( SELECT objid,INVKLASSE,NETTTYPE,NAVN,ALT_NAVN,ON_ID,ON_TYPE,ON_STED_NR,ON_OVER_ID, row_number() over(partition by objid order by objid) as DUP FROM USEROPENNIS ) WHERE dup=2 ) src ON (tgt.objid = src.objid) WHEN MATCHED THEN UPDATE SET tgt.INVKLASSE = COALESCE(tgt.INVKLASSE, src.INVKLASSE), tgt.NETTTYPE = COALESCE(tgt.NETTTYPE, src.NETTTYPE), tgt.NAVN = COALESCE(tgt.NAVN, src.NAVN), tgt.ALT_NAVN = COALESCE(tgt.ALT_NAVN, src.ALT_NAVN), tgt.ON_ID = COALESCE(tgt.ON_ID, src.ON_ID), tgt.ON_TYPE = COALESCE(tgt.ON_TYPE, src.ON_TYPE), tgt.ON_STED_NR = COALESCE(tgt.ON_STED_NR, src.ON_STED_NR), tgt.ON_OVER_ID = COALESCE(tgt.ON_OVER_ID, src.ON_OVER_ID);
COALESCE函数会优先取目标表(tgt)的非空值,若为空则用源表(src)的值,完美实现互补合并。
2. 删除重复的DUP=2记录
DELETE FROM USEROPENNIS WHERE ROWID IN ( SELECT ROWID FROM ( SELECT ROWID, row_number() over(partition by objid order by objid) as DUP FROM USEROPENNIS ) WHERE DUP=2 );
用ROWID定位删除更精准,避免因OBJID重复导致误删。
方案二:临时表中转(更安全)
如果担心直接修改原表出错,可通过临时表先生成合并后的数据,再替换原表:
1. 创建带主键的临时表
CREATE GLOBAL TEMPORARY TABLE TMP_USEROPENNIS ( OBJID NUMBER PRIMARY KEY, INVKLASSE VARCHAR2(100), -- 请根据实际字段类型调整长度 NETTTYPE VARCHAR2(100), NAVN VARCHAR2(100), ALT_NAVN VARCHAR2(100), ON_ID NUMBER, ON_TYPE NUMBER, ON_STED_NR NUMBER, ON_OVER_ID NUMBER ) ON COMMIT PRESERVE ROWS;
2. 插入合并后的数据
利用MAX函数自动忽略NULL值,取同一OBJID下的非空值:
INSERT INTO TMP_USEROPENNIS SELECT OBJID, MAX(INVKLASSE) AS INVKLASSE, MAX(NETTTYPE) AS NETTTYPE, MAX(NAVN) AS NAVN, MAX(ALT_NAVN) AS ALT_NAVN, MAX(ON_ID) AS ON_ID, MAX(ON_TYPE) AS ON_TYPE, MAX(ON_STED_NR) AS ON_STED_NR, MAX(ON_OVER_ID) AS ON_OVER_ID FROM USEROPENNIS GROUP BY OBJID;
3. 替换原表(先备份!)
-- 第一步:备份原表,务必执行! CREATE TABLE USEROPENNIS_BACKUP AS SELECT * FROM USEROPENNIS; -- 第二步:清空原表 TRUNCATE TABLE USEROPENNIS; -- 第三步:插入合并后的数据 INSERT INTO USEROPENNIS SELECT * FROM TMP_USEROPENNIS;
注意事项
- 操作前必须备份原表,避免数据丢失。
- 如果同一OBJID下同一列存在多个非空值,
MAX会取最大值,COALESCE会保留目标表的原值,需根据实际业务确认逻辑。
内容的提问来源于stack exchange,提问作者goldenbutter
相关产品推荐
相关产品推荐

