Oracle 중복 기록 삭제 한 데이터 만 보관 하 는 몇 가지 방법

1. 문제 설명
BBSCOMMENT 표 는 BBSDETAIL 의 종 표 로 상인 평가 정 보 를 기록한다.데이터 가 왔다갔다 하기 때문에 중복 데이터 가 많다.표 구 조 는 다음 과 같다.
COMMENT_ID NOT NULL NUMBER -- 메 인 키 DETAILID NOT NULL NUMBER -- 외부 키, BBSDETAIL 표 COMMENT 참조BODY NOT NULL VARCHAR 2 (500) -- 평가 내용
-- 다른 필드 무시
그 중에서 메 인 키 는 중복 되 지 않 았 고 중복 되 는 것 은 DETAIL 이다.ID+COMMENT_BODY +... 등 정 보 는 일부 업 체 의 평가 정보 가 중복 되 는 것 이다.
2. 해결 절차
2.1 표 의 중복 기록 찾기
--           
select DETAIL_ID,COMMENT_BODY,count(*)
from BBSCOMMENT
group by DETAIL_ID,COMMENT_BODY
having count(*)>1
order by DETAIL_ID, COMMENT_BODY; --1955 

2.2 모든 불필요 한 데 이 터 를 보 여 줍 니 다.
--                 
select min(COMMENT_ID) as COMMENT_ID,DETAIL_ID,COMMENT_BODY
from BBSCOMMENT
group by DETAIL_ID,COMMENT_BODY;   --21453 ,             -1955,   1955    ,         。

2.3 기록 수량 이 적 으 면 위의 문 구 를 하위 조회 로 만 든 다음 에 바로 삭제 할 수 있다.
--          (1    ),                   
delete from BBSCOMMENT where COMMENT_ID not in(
    select min(COMMENT_ID)
    from BBSCOMMENT
    group by DETAIL_ID,COMMENT_BODY
);          --782 ,    ,2    ,    2  (   !!)

2.4 또 다른 삭제 방법
--             ,      ,         
--     :        ;   :    rowid   。
delete from BBSCOMMENT a
where
    (a.DETAIL_ID,a.COMMENT_BODY) in(select DETAIL_ID,COMMENT_BODY from BBSCOMMENT group by DETAIL_ID,COMMENT_BODY having count(*) > 1)
    and rowid not in (select min(rowid) from BBSCOMMENT group by DETAIL_ID,COMMENT_BODY having count(*)>1);

2.5 빅 데 이 터 는 PL / SQL 을 사용 하 는 것 이 편리 하고 빠르다.
declare
--      
type bbscomment_type is record
(
    comment_id BBSCOMMENT.COMMENT_ID%type,
    detail_id BBSCOMMENT.DETAIL_ID%type,
    comment_body BBSCOMMENT.COMMENT_BODY%type
);
bbscomment_record bbscomment_type;

--       
v_comment_id BBSCOMMENT.COMMENT_ID%type;
v_detail_id BBSCOMMENT.DETAIL_ID%type;
v_comment_body BBSCOMMENT.COMMENT_BODY%type;

--    
v_batch_size integer := 5000;
v_counter integer := 0;

cursor cur_dupl is
    --          
    select COMMENT_ID, DETAIL_ID, COMMENT_BODY
    from BBSCOMMENT
    where(DETAIL_ID, COMMENT_BODY) in (
        --       
        select DETAIL_ID, COMMENT_BODY
        from BBSCOMMENT
        group by DETAIL_ID, COMMENT_BODY
        having count(*) > 1)
    order by DETAIL_ID, COMMENT_BODY;
begin
    for bbscomment_record in cur_dupl loop
        if v_detail_id is null or (bbscomment_record.detail_id != v_detail_id or nvl(bbscomment_record.comment_body, ' ') != nvl(v_comment_body, ' ')) then
            --    、    ,     
            v_detail_id := bbscomment_record.detail_id;
            v_comment_body := bbscomment_record.comment_body;
        else
            --      
            delete from BBSCOMMENT where COMMENT_ID = bbscomment_record.comment_id;
            v_counter := v_counter + 1;

            if mod(v_counter, v_batch_size) = 0 then
                --        
                commit;
            end if;
        end if;
    end loop;

    if v_counter > 0 then
        --      
        commit;
    end if;

    dbms_output.put_line(to_char(v_counter)||'');
exception
    when others then
        dbms_output.put_line('sqlerrm-->' ||sqlerrm);
        rollback;
end;

좋은 웹페이지 즐겨찾기