从Oracle中删除表中的重复行
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从Oracle中删除表中的重复行相关的知识,希望对你有一定的参考价值。
我正在Oracle中测试一些东西,并用一些示例数据填充了一个表,但是在这个过程中我不小心加载了重复的记录,所以现在我无法使用某些列创建主键。
如何删除所有重复的行并只留下其中一行?
答案
使用rowid
伪列。
DELETE FROM your_table
WHERE rowid not in
(SELECT MIN(rowid)
FROM your_table
GROUP BY column1, column2, column3);
column1
,column2
和column3
构成每条记录的识别密钥。您可以列出所有列。
另一答案
Solution 4)
delete from emp where rowid in
(
select rid from
(
select rowid rid,
dense_rank() over(partition by empno order by rowid
) rn
from emp
)
where rn > 1
);
另一答案
解决方案
delete from emp
where rowid not in
(select max(rowid) from emp group by empno);
解决方案
delete from emp where rowid in
(
select rid from
(
select rowid rid,
row_number() over(partition by empno order by empno) rn
from emp
)
where rn > 1
);
3.solution
delete from emp e1
where rowid not in
(select max(rowid) from emp e2
where e1.empno = e2.empno );
解决方案
delete from emp where rowid in
(
select rid from
(
select rowid rid,
dense_rank() over(partition by empno order by rowid
) rn
from emp
)
where rn > 1
);
另一答案
5.解决方案
delete from emp where rowid in
(
select rid from
(
select rowid rid,rank() over (partition by emp_id order by rowid)rn from emp
)
where rn > 1
);
另一答案
DELETE from table_name where rowid not in (select min(rowid) FROM table_name group by column_name);
您还可以用其他方式删除重复记录
DELETE from table_name a where rowid > (select min(rowid) FROM table_name b where a.column=b.column);
另一答案
create table abcd(id number(10),name varchar2(20))
insert into abcd values(1,'abc')
insert into abcd values(2,'pqr')
insert into abcd values(3,'xyz')
insert into abcd values(1,'abc')
insert into abcd values(2,'pqr')
insert into abcd values(3,'xyz')
select * from abcd
id Name
1 abc
2 pqr
3 xyz
1 abc
2 pqr
3 xyz
Delete Duplicate record but keep Distinct Record in table
DELETE
FROM abcd a
WHERE ROWID > (SELECT MIN(ROWID) FROM abcd b
WHERE b.id=a.id
);
run the above query 3 rows delete
select * from abcd
id Name
1 abc
2 pqr
3 xyz
另一答案
DELETE FROM tableName WHERE ROWID NOT IN (SELECT MIN (ROWID) FROM table GROUP BY columnname);
另一答案
delete from dept
where rowid in (
select rowid
from dept
minus
select max(rowid)
from dept
group by DEPTNO, DNAME, LOC
);
另一答案
真正大桌子的最快方式
- 创建具有以下结构的异常表:exceptions_table
ROW_ID ROWID OWNER VARCHAR2(30) TABLE_NAME VARCHAR2(30) CONSTRAINT VARCHAR2(30)
- 尝试创建一个唯一的约束或主键,重复项将违反。您将收到错误消息,因为您有重复项。例外表将包含重复行的rowid。
alter table add constraint unique --or primary key (dupfield1,dupfield2) exceptions into exceptions_table;
- 通过rowid加入您的表和exceptions_table并删除dups
delete original_dups where rowid in (select ROW_ID from exceptions_table);
- 如果要删除的行数很大,则创建一个新表(包含所有授权和索引),使用rowid反例例连接exceptions_table,并将原始表重命名为original_dups表,并将new_table_with_no_dups重命名为原始表
create table new_table_with_no_dups AS ( select field1, field2 ........ from original_dups t1 where not exists ( select null from exceptions_table T2 where t1.rowid = t2.row_id ) )
另一答案
检查下面的脚本 -
1.
Create table test(id int,sal int);
2.
insert into test values(1,100);
insert into test values(1,100);
insert into test values(2,200);
insert into test values(2,200);
insert into test values(3,300);
insert into test values(3,300);
commit;
3.
select * from test;
你会在这里看到6条记录。 4.run以下查询 -
delete from
test
where rowid in
(select rowid from
(select
rowid,
row_number()
over
(partition by id order by sal) dup
from test)
where dup > 1)
select * from test;
您将看到已删除重复记录。 希望这能解决您的疑问。谢谢 :)
另一答案
我没有看到任何使用公用表表达式和窗口函数的答案。这是我最容易使用的。
DELETE FROM
YourTable
WHERE
ROWID IN
(WITH Duplicates
AS (SELECT
ROWID RID,
ROW_NUMBER()
OVER(
PARTITION BY First_Name, Last_Name, Birth_Date)
AS RN
SUM(1)
OVER(
PARTITION BY First_Name, Last_Name, Birth_Date
ORDER BY ROWID ROWS BETWEEN UNBOUNDED PRECEDING
AND UNBOUNDED FOLLOWING)
AS CNT
FROM
YourTable
WHERE
Load_Date IS NULL)
SELECT
RID
FROM
duplicates
WHERE
RN > 1);
有些事要注意:
1)我们只检查partition子句中字段的重复。
2)如果您有某种理由选择一个副本而不是其他副本,您可以使用order by子句使该行具有row_number()= 1
3)您可以通过将最终where子句更改为“Where RN> N”来更改保留的数字,其中N> = 1(我认为N = 0将删除所有具有重复项的行,但它只会删除所有行) 。
4)在CTE查询中添加了Sum分区字段,该查询将使用组中的数字行标记每一行。因此,要选择具有重复项的行,包括第一项使用“WHERE cnt> 1”。
另一答案
来自Ask Tom
delete from t
where rowid IN ( select rid
from (select rowid rid,
row_number() over (partition by
companyid, agentid, class , status, terminationdate
order by rowid) rn
from t)
where rn <> 1);
(修正了缺失的括号)
另一答案
create or replace procedure delete_duplicate_enq as
cursor c1 is
select *
from enquiry;
begin
for z in c1 loop
delete enquiry
where enquiry.enquiryno = z.enquiryno
and rowid > any
(select rowid
from enquiry
where enquiry.enquiryno = z.enquiryno);
end loop;
end delete_duplicate_enq;
另一答案
为了获得最佳性能,我写的是: (见执行计划)
DELETE FROM your_table
WHERE rowid IN
(select t1.rowid from your_table t1
LEFT OUTER JOIN (
SELECT MIN(rowid) as rowid, column1,column2, column3
FROM your_table
GROUP BY column1, column2, column3
) co1 ON (t1.rowid = co1.rowid)
WHERE co1.rowid IS NULL
);
另一答案
方案:
delete from emp where rowid in
(
select rid from
(
select rowid rid,
row_number() over(partition by empno order by empno) rn
from emp
)
where rn > 1
);
另一答案
来自DevX.com:
DEL以上是关于从Oracle中删除表中的重复行的主要内容,如果未能解决你的问题,请参考以下文章