ORACLEは、重複データを削除します

 
 
 
 
クエリSQL文と重複するレコードを削除します
 
図1に示すように、冗長なルックアップテーブルの重複レコード、重複レコードを決定するために単一のフィールド(ID)に基づいています
 
(そのフィールドの重複にルックアップテーブル) - 数(ID)> 1を持つテーブル群からIDを選択しbyId
 
同上表SELECT * FROM(テーブル群からIDを選択カウント(ID)を有するbyId> 1) - (データに従ってチェックフィールドを複製し、関連するすべてのレコードを照会)
 
図2に示すように、単一のフィールドが繰り返し記録されているに基づいて、テーブル内の冗長重複レコードを削除する(Id)が唯一の最小記録行IDを残して、決定します
 
WHERE(ID)IN(COUNT(IDを持つIDによって表グループからIDを選択)> 1)AND ROWID NOT IN(COUNT(*)を有するIDによって表群からMIN(ROWID)を選択> 1)表から削除します。
 
フィールド決意重複データは、冗長データは、最小の記録のみROWID(行数)を残して、除去されます
 
 
 
3、余分なルックアップテーブルが繰り返し記録されている(複数のフィールド)
 
(1> IDを選択し、IDによる表からグループ配列、配列を有する数(*))における場合(a.Id、a.seq)表SELECT * FROM
 
唯一の最小記録行IDを残し4、テーブルが削除される冗長な重複(複数のフィールド)
 
Idでから表基分(行ID)を選択中の場合(a.Id、a.seq)表から削除(配列カウント(*)を有する、ID、IDによってグループ表からの配列を選択> 1)と(していない行識別子、SEQ持つCOUNT(*)> 1)
 
5、ルックアップテーブルを繰り返し、余分な(複数のフィールド)を記録し、最小記録のROWIDが含まれていません
 
(1> ID、IDがグループ表からの配列を選択し、配列を有する数(*))における場合(a.Id、a.seq)表SELECT * FROMとから表基(MINを選択し(ROWID)にによるもののROWID ID、SEQ持つCOUNT(*)> 1)
 
 

:データフィールドを繰り返して単一に応じて決定されます

1、まず第一に、キーフィールド(名前)によって、ルックアップテーブルの冗長データを照会します。

名前にはOA_ADDRESS_BOOK SELECT * FROM(数(名)を持つ名前でOA_ADDRESS_BOOKグループから名前を選択> 1)

 

図2に示すように、テーブル内の重複データを削除し、単一のフィールド重複データ(名前)のみ最小記録行IDを残し、に応じて決定されます

OA_ADDRESS_BOOK(名前)でから、削除 

(> 1)名前を有する数(名前によってOA_ADDRESS_BOOK群から名前を選択) 

そして、されていない行識別子(名前カウント(Name)を有することによってOA_ADDRESS_BOOK群から選択分(ROWID)> 1)

 

II:決意は、複数のデータフィールドを繰り返します

図1は、まず、重複データルックアップテーブルは、キーフィールド(名前、UNIT_ID)を照会します。

ここで(book1.name、book1.unit_id)OA_ADDRESS_BOOKのBOOK1 SELECT * FROM 
(book2.nameによってOA_ADDRESS_BOOKのBOOK2群からbook2.nameを選択し、book2.unit_id、COUNT(*)を有するbook2.unit_id> 1)

 

図2に示すように、重複データテーブルを削除し、データは、最小記録行IDを残して、決定するためのフィールド(名前、UNIT_ID)複数の繰り返されます

 

 

OA_ADDRESS_BOOKどこから(a.Name、a.UNIT_ID)で削除 
(UNIT_IDカウント(*)を有する、名前によってOA_ADDRESS_BOOK群から名前、UNIT_IDを選択> 1) 
と名前によってOA_ADDRESS_BOOKグループから(セレクト分(ROWID)にない行識別子、UNIT_IDカウントを持つ(*)> 1)

図3に示すように、重複データのルックアップテーブルは、データフィールド(名前、UNIT_ID)決定された複数の繰り返され、記録が最小行IDが含まれていません
 
名前を選択し、OA_ADDRESS_BOOKからUNIT_IDにおける場合(a.Name、a.UNIT_ID) 
(COUNT(*)を有するUNIT_ID、名前によってOA_ADDRESS_BOOK群から名前、UNIT_IDを選択> 1) 
とOA_ADDRESS_BOOKから(セレクト分(ROWID)にない行識別子名前、UNIT_ID持つCOUNT(*)>でグループ1)
 
 

1.問題の説明

テーブル、評価・レコード・ビジネス情報からBBSCOMMENTテーブルBBSDETAIL。データとシフトがgoをシフトするので、重複データがたくさんあります。次のようにテーブルの構造は次のとおりです。

COMMENT_ID、NOT NULL NUMBER -プライマリキー
DETAIL_ID NOT NULL NUMBER -外部キー参照BBSDETAILテーブル
COMMENT_BODY NOT NULL VARCHAR2(500) -コンテンツの評価

- 他のフィールドを無視します

これには主キーが繰り返し、繰り返しがDETAIL_ID + COMMENT_BODY +である......と、他の情報はないが、評価情報は、一部の企業が重複しています。

2.解決手順

2.1ルックアップテーブルの不要な重複レコード

コードをコピー
コードをコピー
-すべての重複データを照会する
SELECT DETAIL_ID、Comment_Body、COUNT(*)を
BBSCOMMENTから
DETAIL_ID、Comment_Bodyによってグループ
。> COUNT(*)を有する1つの
DETAIL_ID、Comment_Body順; --1 955バー
コードをコピー
コードをコピー

2.2は、すべての非冗長データを示します

-このコマンドは、すべての非冗長データを示す
COMMENT_ID、DETAIL_ID、Comment_Body AS SELECT分(COMMENT_ID)
BBSCOMMENTから
DETAIL_ID、Comment_Bodyによってグループ;この値は、テーブル内のレコードの総数に等しくない理由--21,453バー、-1955 1955年の記録ので、いくつかは複数回繰り返しました。

2.3記録(千のレベル)の数が少ない、上記のステートメントは、サブクエリを作ることができるならば、削除します

コードをコピー
コードをコピー
-テーブルが大量のデータ(1未満千)がない場合、上記のステートメントは、サブクエリを行い、その後、削除されてもよい
BBSCOMMENTから削除WHERE COMMENT_ID NOT IN(
    SELECT分(COMMENT_ID)
    BBSCOMMENTから
    DETAIL_IDによってグループ、Comment_Body 
)。私の代わりに--782秒、20,000レコード、重複したレコード2,000人以上(遅すぎます!)
コードをコピー
コードをコピー

別の2.4 Deleteメソッド

コードをコピー
コードをコピー
-このステートメントは、上記の機能を実現するが、テストすることはできません、私のデータが削除された
-の条件を削除するには:重複したレコードは、データがある;第二の条件:最小のROWIDを記録しておきます。
削除からBBSCOMMENT 
    中(a.DETAIL_ID、a.COMMENT_BODY)(Comment_Body、DETAIL_IDによってグループBBSCOMMENTからDETAIL_ID、Comment_BodyをSELECTはCOUNT(*)を持つ>。1)
    DETAIL_IDによってグループBBSCOMMENTからとROWID NOT IN(SELECT分(ROWID) 、COMMENT_BODYは> COUNT(*)を有する )1。
コードをコピー
コードをコピー

2.5大量のデータやPL / SQLは、便利な使用

コードをコピー
コードをコピー
DECLARE 
-定義ストレージ構造
型bbscomment_typeはレコードである
    comment_id型BBSCOMMENT.COMMENT_ID%で
    detail_id型BBSCOMMENT.DETAIL_ID%で
    Comment_Body型BBSCOMMENT.COMMENT_BODYの%
); 
bbscomment_record bbscomment_type; 

-変数匹敵ため
v_comment_idのBBSCOMMENT.COMMENT_ID%のタイプ; 
%のBBSCOMMENT.DETAIL_ID型v_detail_id; 
v_comment_body BBSCOMMENT.COMMENT_BODY%のタイプ; 

-他の変数は
整数v_batch_size:= 5000; 
整数v_counter:= 0; 

カーソルcur_duplは、
    -すべての重複レコードを削除
    COMMENT_ID、DETAIL_ID、Comment_Bodyを選択
    BBSCOMMENTから
    WHERE (DETAIL_ID、COMMENT_BODY)(中 
        -重複レコード
        DETAIL_ID SELECT、Comment_Body 
        BBSCOMMENTから
        DETAIL_ID、Comment_Bodyによってグループ
        HAVING COUNT(*)> 1)。
    DETAIL_ID、Comment_Body順; 
始める
    cur_duplループにbbscomment_recordのために
        !またはnullの場合v_detail_id(またはv_detail_id bbscomment_record.detail_id = NVL(bbscomment_record.comment_body、 '')= NVL(v_comment_body、! 'を'))
            -初めて入力するために、記録のために、再割り当てされ
            v_detail_id:= bbscomment_record.detail_id; 
            v_comment_body:= bbscomment_record.comment_body; 
        他の
            -別のレコードが削除
            BBSCOMMENTどこから削除COMMENT_ID = bbscomment_record.comment_id。
            v_counter:。+ = v_counterは1;
 
            MOD(v_counter、v_batch_size)= 0次いで、IF
                -毎回どのように多くの提出
                コミットし; 
            END IF; 
        END IF; 
    エンドループ; 

    v_counter> 0なら、
        -最後のコミット
        コミット; 
    END IF; 

    DBMS_OUTPUT.PUT_LINE(TO_CHAR(v_counter)|| 'レコードが削除されます!' ); 
例外
    た場合、その後その他
        DBMS_OUTPUT.PUT_LINE( 'SQLERRM - >' || SQLERRM); 
        ROLLBACK; 
END;

おすすめ

転載: www.cnblogs.com/JIKes/p/11583687.html