有时候因未进行数据验证或其他特殊场景,导致数据表中出现重复的数据,需要对重复数据进行删除,并且只保留其中一条。
一、当数据表存在主键时,可使用 ROW_NUMBER 进行排序后删除,参考脚本如下:
删除带有主键的重复数据
DELETE FROM DUPLICATES_TABLE
WHERE ID IN (
SELECT ID
FROM (
SELECT ID,
ROW_NUMBER() OVER (PARTITION BY COLUMN1, COLUMN2 ORDER BY ID) AS ROW_NUM
FROM DUPLICATES_TABLE
)
WHERE ROW_NUM > 1 --只保留第一行,删除其余同ID的重复行
);
二、当数据表缺少主键时,可使用 ROWID 进行排序后删除,参考脚本如下:
删除前建议先备份
-- 备份
CREATE TABLE MY_TMNL_EQUIP_PARAM_BACK AS
SELECT TB.* FROM MY_TMNL_EQUIP_PARAM TB
JOIN (
SELECT T.OPER_ID,
T.PARA_ID,
COUNT(T.OPER_ID) SL
FROM MY_TMNL_EQUIP_PARAM T
WHERE T.PARA_ID IN
(SELECT B.CSBS
FROM SB_FKZDCS B)
GROUP BY T.OPER_ID, T.PARA_ID
HAVING COUNT(T.OPER_ID) > 1
ORDER BY T.OPER_ID DESC
) TA ON TB.OPER_ID=TA.OPER_ID AND TB.PARA_ID=TA.PARA_ID;
遍历批量删除
--删除
BEGIN
FOR TTT IN ( --查找出重复数据
SELECT T.OPER_ID,
T.PARA_ID,
COUNT(T.OPER_ID) SL
FROM MY_TMNL_EQUIP_PARAM T
WHERE T.PARA_ID IN
(SELECT B.CSBS
FROM SB_FKZDCS B)
GROUP BY T.OPER_ID, T.PARA_ID
HAVING COUNT(T.OPER_ID) > 1
ORDER BY T.OPER_ID DESC
)
LOOP --遍历删除(只保留每组重复的第一条)
--DBMS_OUTPUT.put_line(TTT.OPER_ID);
DELETE FROM MY_TMNL_EQUIP_PARAM T WHERE T.OPER_ID=TTT.OPER_ID
AND ROWID<> --只保留第一行,删除其余相同重复行
(
SELECT MIN(ROWID) FROM MY_TMNL_EQUIP_PARAM T1 WHERE T1.OPER_ID=TTT.OPER_ID
);
END LOOP;
COMMIT;
END;