在Oracle中使用合并删除重复项

vu8f3i0k  于 2023-06-22  发布在  Oracle
关注(0)|答案(2)|浏览(266)

我有一个没有主键的表,其中OBJID列上有超过13,000条记录是重复的,但其他列中的值不同。我想把两个重复的记录合并成一个。有没有可能用merge语句来完成这一点,或者我需要用循环更新表并手动修复它?
下面是该表的外观:

OBJID,INVKLASSE,NETTYPE,NAVN,ALT_NAVN,ON_ID,ON_TYPE,ON_STED_NR,ON_OVER_ID-219468,NYINVESTERING,,,,,,,,,,,,,-219468,,,,,,,,,,,,,277615,50,277614,-99-218981,NYINVESTERING,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-218761,,,,,,,277909,50,277908,-99-218709,NYINVESTERING,,,,,,,,,,,,,,,,,,,218709,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
我已经创建了一个临时表,我试图插入所有重复的记录,其中OBJID是主键。

select * 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;

我已经创建了一些类似这样的SQL来分隔DUP = 1或2的所有重复记录。所有DUP = 1都可以作为唯一记录插入,但是DUP = 2是13,000条记录,我需要更新所有列都为null或类似的表。
我正在寻找任何可以快速修复它的建议。
预期输出。

ne5o7dgx

ne5o7dgx1#

要将重复的记录折叠成一个,同时从每个记录中选择列值,您需要在主键上使用GROUP BY,并在所有非键列周围使用聚合函数(如MAX),每个聚合中可能有DECODE/CASE,它们试图决定优先考虑哪些值。
如果您唯一的问题是某些行的所有列都有NULL,而其他行有数据,那么请删除具有NULL值的行。或者,如果它是混合的,但仍然只有NULL与非NULL问题,MAX本身将挑选出非NULL值。如果比这更复杂,并且有多个非NULL值可供选择,则必须编写逻辑来选择所需的值。
简单来说:

SELECT objid,
       MAX(invklasse),MAX(nettype),MAX(navn), etc...
  FROM USEROPENNIS
GROUP BY objid

更复杂(这可以看起来像任何东西,这只是给出了大致的想法):

SELECT objid,
       MAX(NULLIF(invklasse,'BADVALUE')),
       SUBSTR(MIN(DECODE(nettype,'nicevalue','1','lessnicevalue','2','3')||nettype),2) nettype, etc..
  FROM USEROPENNIS
GROUP BY objid

一旦你在SELECT查询中获得了你想要的数据,你就可以把你想出来的查询放在CTAS中来创建一个临时表:

CREATE TABLE tmp$1 AS SELECT ...

现在截断原始表,并将临时表的内容插入其中:

TRUNCATE TABLE useropennis;
INSERT /*+ append */ INTO useropennis SELECT * FROM tmp$1;
COMMIT;

现在在上面创建一个PK,这样你就不会再次陷入这种情况:

ALTER TABLE useropennis ADD CONSTRAINT pk_useropennis PRIMARY KEY (objid);
jutyujz0

jutyujz02#

创建一个新表,如下所示

CREATE TABLE USEROPENNIS (objid int, INVKLASSE varchar2(10))
INSERT INTO USEROPENNIS VALUES (12,NULL)
INSERT INTO USEROPENNIS VALUES (12,'A')
INSERT INTO USEROPENNIS VALUES (14,'B')
INSERT INTO USEROPENNIS VALUES (14,NULL)
CREATE TABLE new_table AS SELECT objid , MAX(INVKLASSE) as INVKLASSE FROM USEROPENNIS GROUP BY  objid
2 rows affected
SELECT * FROM new_table

| OBJID| INVKLASSE|
| - -----|- -----|
| 十二岁|一个|
| 十四|B|
fiddle
然后删除旧表
然后呢

RENAME new_table TO USEROPENNIS ;

相关问题