Answers:
使用rowid
伪列。
DELETE FROM your_table
WHERE rowid not in
(SELECT MIN(rowid)
FROM your_table
GROUP BY column1, column2, column3);
其中column1
,column2
和column3
组成每个记录的标识键。您可能会列出所有列。
DELETE FROM tablename a
WHERE a.ROWID > ANY (SELECT b.ROWID
FROM tablename b
WHERE a.fieldname = b.fieldname
AND a.fieldname2 = b.fieldname2)
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
);
delete from emp e1
where rowid not in
(select max(rowid) from emp e2
where e1.empno = e2.empno );
您应该使用游标进行循环来做一个小的pl / sql块,并删除您不想保留的行。例如:
declare
prev_var my_table.var1%TYPE;
begin
for t in (select var1 from my_table order by var 1) LOOP
-- if previous var equal current var, delete the row, else keep on going.
end loop;
end;
要选择重复项,仅查询格式可以是:
SELECT GroupFunction(column1), GroupFunction(column2),...,
COUNT(column1), column1, column2...
FROM our_table
GROUP BY column1, column2, column3...
HAVING COUNT(column1) > 1
因此,根据其他建议的正确查询是:
DELETE FROM tablename a
WHERE a.ROWID > ANY (SELECT b.ROWID
FROM tablename b
WHERE a.fieldname = b.fieldname
AND a.fieldname2 = b.fieldname2
AND ....so on.. to identify the duplicate rows....)
该查询将在数据库中保留最古老的记录,以用于中选择的标准WHERE CLAUSE
。
Oracle认证助理(2008)
真正大桌子的最快方法
创建具有以下结构的异常表:exceptions_table
ROW_ID ROWID
OWNER VARCHAR2(30)
TABLE_NAME VARCHAR2(30)
CONSTRAINT VARCHAR2(30)
尝试创建唯一的约束或主键,这些约束或主键将被重复项所违反。您将收到一条错误消息,因为您有重复项。例外表将包含重复行的行ID。
alter table add constraint
unique --or primary key
(dupfield1,dupfield2) exceptions into exceptions_table;
通过rowid将表与exceptions_table联接在一起,并删除重复项
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 )
)
使用rowid-
delete from emp
where rowid not in
(select max(rowid) from emp group by empno);
使用自我加入-
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
);
1.解决方案
delete from emp
where rowid not in
(select max(rowid) from emp group by empno);
2.偷偷摸摸
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.解决方案
delete from emp e1
where rowid not in
(select max(rowid) from emp e2
where e1.empno = e2.empno );
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
);
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 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
);
检查以下脚本-
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.运行以下查询-
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)您可以通过将final where子句更改为“ Where RN> N”(其中N> = 1)来更改保留的重复数(我以为N = 0会删除所有重复的行,但只会删除所有行) 。
4)在“总和”分区字段中添加了CTE查询,该字段将使用组中的数字行标记每一行。因此,要选择包含重复项的行(包括第一项),请使用“ WHERE cnt> 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;