我想选择/删除多个表中的所有重复行。我在互联网上搜索线索,但我看到的都是基于一个或多个列选择重复行的查询。如下所示:SELECT col1 count(*) from table_name group by col1 having count(*) > 1 我想要实现的是基于ALL COLUMNS选择重复的行,只要它们在每列中的所有值都相同。 我正在处理多个表,所以我希望它是通用的,这样它就可以在任何表上工作。
DELETE FROM table_name
WHERE ROWID IN (
SELECT ROWID
FROM (
SELECT ROW_NUMBER() OVER (
PARTITION BY col1, col2, col3, /*...,*/ colN -- List all the columns
ORDER BY ROWID
) AS rn
FROM table_name
)
WHERE rn > 1
);
如果要删除所有重复项的所有副本,请执行以下操作:
DELETE FROM table_name
WHERE ROWID IN (
SELECT ROWID
FROM (
SELECT COUNT(*) OVER (
PARTITION BY col1, col2, col3, /*...,*/ colN -- List all the columns
) AS cnt
FROM table_name
)
WHERE cnt > 1
);
declare
l_column_list varchar2(32767);
l_table_name varchar2(4000) := 'AAAA_DATES';
begin
for rec in (select column_name, column_id
from dba_tab_cols
where table_name = l_table_name
order by column_id) loop
if (rec.column_id = 1) then
l_column_list := rec.column_name;
else
l_column_list := l_column_list || ',' || rec.column_name;
end if;
end loop;
execute immediate 'DELETE FROM ' || l_table_name ||
' WHERE ROWID IN (
SELECT ROW_id
FROM (
SELECT rowid row_id, ROW_NUMBER() OVER (
PARTITION BY ' || l_column_list ||
' ORDER BY ROWNUM
) AS rn
FROM ' || l_table_name || '
)
WHERE rn > 1
)';
dbms_output.put_line(sql%rowcount);
commit;
end;
2条答案
按热度按时间olmpazwi1#
如果要删除重复项并保留每一行的第一个示例,则可以在
ROWID
伪列上的delete和correlate中使用子查询,并在每个组中查找ROW_NUMBER
大于1的行:如果要删除所有重复项的所有副本,请执行以下操作:
nfeuvbwi2#
我采用了MTO的答案,并做了一些更正和更通用的