문제

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
);

정말 큰 테이블을위한 가장 빠른 방법

  1. 아래 구조가있는 예외 테이블을 만듭니다 : exceptions_table

    ROW_ID ROWID
    OWNER VARCHAR2(30)
    TABLE_NAME VARCHAR2(30)
    CONSTRAINT VARCHAR2(30)
    
  2. 중복에 의해 위반 될 고유 한 제약 또는 기본 키를 작성하십시오. 복제본이 있으므로 오류 메시지가 표시됩니다. 예외 테이블에는 중복 행의 Rowids가 포함됩니다.

    alter table add constraint
    unique --or primary key
    (dupfield1,dupfield2) exceptions into exceptions_table;
    
  3. rowid의 exceptions_table과 함께 테이블에 가입하고 dups 삭제

    delete original_dups where rowid in (select ROW_ID from exceptions_table);
    
  4. 삭제할 행의 양이 큰 경우 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)
  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
);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top