質問

Oracle で何かをテストしており、テーブルにサンプル データを入力しましたが、その過程で誤って重複したレコードを読み込んだため、一部の列を使用して主キーを作成できなくなりました。

重複した行をすべて削除し、そのうちの 1 行だけを残すにはどうすればよいですか?

役に立ちましたか?

解決

rowid疑似列を使用します。

DELETE FROM your_table
WHERE rowid not in
(SELECT MIN(rowid)
FROM your_table
GROUP BY column1, column2, column3);

どこcolumn1column2、およびcolumn3は、各レコードの識別キーを構成します。あなたは、すべての列を一覧表示することがあります。

他のヒント

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 * FROM別個としてテーブル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に選ばれた基準のデータベース内の最も古い記録を保持します。

オラクル認定アソシエイト(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. 以下の構造の例外テーブルを作成します。例外テーブル

    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 によってテーブルを例外テーブルに結合し、重複を削除します

    delete original_dups where rowid in (select ROW_ID from exceptions_table);
    
  4. 削除する行の量が多い場合は、ROWID による例外テーブルとのアンチ結合の新しいテーブル (すべての許可とインデックスを含む) を作成し、元のテーブルの名前を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を持つことになり、その行を作るためにORDER BY句を使用することができ、他の上に1つの重複を選択するためにいくつかの理由がある場合は()= 1

3)あなたは、最終的に変更して保存番号の重複を変更することができますwhere句に「どこRN> N」N> = 1(Iは、N = 0の重複を持っているすべての行を削除だろうと考えましたが、それは単に削除しますとすべての行)。

4)合計パーティションフィールドをグループ内の数字列と各行をタグ付けしますCTEクエリを追加しました。だから、「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