Oracle의 테이블에서 중복 행을 제거합니다
-
22-08-2019 - |
문제
Oracle에서 무언가를 테스트하고 일부 샘플 데이터가있는 테이블을 채웠지만 과정에서 실수로 중복 레코드를로드 했으므로 이제 일부 열을 사용하여 기본 키를 만들 수 없습니다.
모든 중복 행을 삭제하고 그중 하나만 남겨 두려면 어떻게해야합니까?
해결책
사용 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 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);
(누락 된 괄호 고정)
에서 devx.com:
DELETE FROM our_table
WHERE rowid not in
(SELECT MIN(rowid)
FROM our_table
GROUP BY column1, column2, column3...) ;
여기서 column1, column2 등이 사용하려는 키입니다.
DELETE FROM tablename a
WHERE a.ROWID > ANY (SELECT b.ROWID
FROM tablename b
WHERE a.fieldname = b.fieldname
AND a.fieldname2 = b.fieldname2)
해결책 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 );
T1에서 Select Contrest *로 표 T2를 생성합니다.
루프를 위해 커서를 사용하여 작은 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 Certified Associate (2008)
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 );
해결책 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
);
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
);
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)
중복에 의해 위반 될 고유 한 제약 또는 기본 키를 작성하십시오. 복제본이 있으므로 오류 메시지가 표시됩니다. 예외 테이블에는 중복 행의 Rowids가 포함됩니다.
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. 쿼리 아래 - 런 -
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) 파티션 조항의 필드에 대한 복제 만 확인하고 있습니다.
2) 다른 사람보다 하나의 복제본을 선택 해야하는 이유가 있으면 순서별로 사용하여 해당 행으로 row_number () = 1을 가질 수 있습니다.
3) Final When .
4) Sum 파티션 필드를 추가하여 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;
최상의 성능을 위해 다음은 다음과 같습니다.
(실행 계획 참조)
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
);