wake-up-neo.com

Doppelte Zeilen aus der Tabelle in Oracle entfernen

Ich teste etwas in Oracle und fülle eine Tabelle mit Beispieldaten auf. Dabei habe ich jedoch versehentlich doppelte Datensätze geladen, sodass ich mit einigen Spalten keinen Primärschlüssel erstellen kann.

Wie kann ich alle doppelten Zeilen löschen und nur eine davon belassen?

131
juan

Verwenden Sie die Pseudospalte rowid.

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

Wo column1, column2, und column3 bilden den Identifizierungsschlüssel für jeden Datensatz. Möglicherweise listen Sie alle Ihre Spalten auf.

267
Bill the Lizard

Von Frag Tom

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

(korrigiert die fehlende Klammer)

15
Dead Programmer
DELETE FROM tablename a
      WHERE a.ROWID > ANY (SELECT b.ROWID
                             FROM tablename b
                            WHERE a.fieldname = b.fieldname
                              AND a.fieldname2 = b.fieldname2)
11
user187624

Von DevX.com :

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

Wobei Spalte1, Spalte2 usw. der Schlüssel ist, den Sie verwenden möchten.

11
Mark

Lösung 1)

delete from emp
where rowid not in
(select max(rowid) from emp group by empno);

Lösung 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
               );

Lösung 3)

delete from emp e1
         where rowid not in
          (select max(rowid) from emp e2
           where e1.empno = e2.empno ); 
7
DoOrDie

erstelle die Tabelle t2 als select distinct * from t1;

6
Mohammed khaled

Um die Duplikate auszuwählen, kann nur das Abfrageformat sein:

SELECT GroupFunction(column1), GroupFunction(column2),..., 
COUNT(column1), column1, column2...
FROM our_table
GROUP BY column1, column2, column3...
HAVING COUNT(column1) > 1

Die richtige Abfrage laut einem anderen Vorschlag lautet also:

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

Diese Abfrage speichert den ältesten Datensatz in der Datenbank für die in WHERE CLAUSE Ausgewählten Kriterien.

Oracle Certified Associate (2008)

3
user1799846

Sie sollten einen kleinen pl/sql-Block mit einem Cursor für die Schleife erstellen und die Zeilen löschen, die Sie nicht behalten möchten. Zum Beispiel:

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;
3
Nick
DELETE from table_name where rowid not in (select min(rowid) FROM table_name group by column_name);

sie können doppelte Datensätze auch auf andere Weise löschen

DELETE from table_name a where rowid > (select min(rowid) FROM table_name b where a.column=b.column);
2
Md Wasi
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
2
Krunal Patel

Lösung 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
);
2
DoOrDie

1. Lösung

delete from emp
    where rowid not in
    (select max(rowid) from emp group by empno);

2. Lösung

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

.Lösung

delete from emp e1
         where rowid not in
          (select max(rowid) from emp e2
           where e1.empno = e2.empno ); 

4. Lösung

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

Rowid-

delete from emp
 where rowid not in
 (select max(rowid) from emp group by empno);

Verwenden von Self-Join-

delete from emp e1
 where rowid not in
 (select max(rowid) from emp e2
 where e1.empno = e2.empno );
2

5. Lösung

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

Der schnellste Weg für wirklich große Tische

  1. Erstellen Sie eine Ausnahmetabelle mit der folgenden Struktur: exceptions_table

    ROW_ID ROWID
    OWNER VARCHAR2(30)
    TABLE_NAME VARCHAR2(30)
    CONSTRAINT VARCHAR2(30)
    
  2. Versuchen Sie, eine eindeutige Einschränkung oder einen eindeutigen Primärschlüssel zu erstellen, gegen die bzw. den die Duplikate verstoßen. Sie erhalten eine Fehlermeldung, weil Sie Duplikate haben. Die Ausnahmetabelle enthält die Zeilen-IDs für die doppelten Zeilen.

    alter table add constraint
    unique --or primary key
    (dupfield1,dupfield2) exceptions into exceptions_table;
    
  3. Verbinden Sie Ihren Tisch mit exceptions_table by rowid und löschen Sie dups

    delete original_dups where rowid in (select ROW_ID from exceptions_table);
    
  4. Wenn die Anzahl der zu löschenden Zeilen groß ist, erstellen Sie eine neue Tabelle (mit allen Berechtigungen und Indizes), die das Verknüpfen mit exceptions_table by rowid verhindert, und benennen Sie die Originaltabelle in original_dups table und new_table_with_no_dups in original table um

    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
user2158672
delete from dept
where rowid in (
     select rowid
     from dept
     minus
     select max(rowid)
     from dept
     group by DEPTNO, DNAME, LOC
);
1
user3655760
DELETE FROM tableName  WHERE ROWID NOT IN (SELECT   MIN (ROWID) FROM table GROUP BY columnname);
1
JgSudhakar

Überprüfen Sie die folgenden Skripte -

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;    

Sie sehen hier 6 Datensätze.
4.Unter Abfrage ausführen -

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;

Sie werden sehen, dass doppelte Datensätze gelöscht wurden.
Hoffe, dies löst Ihre Anfrage. Vielen Dank :)

1
Rakesh Roshan

Ich habe keine Antworten gefunden, die allgemeine Tabellenausdrücke und Fensterfunktionen verwenden. Damit kann ich am einfachsten arbeiten.

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

Was zu beachten ist:

1) Wir prüfen nur die Felder in der Partitionsklausel auf Duplizierung.

2) Wenn Sie einen Grund haben, ein Duplikat vor anderen zu wählen, können Sie eine order by -Klausel verwenden, damit diese Zeile row_number () = 1 hat

3) Sie können das erhaltene Nummernduplikat ändern, indem Sie die letzte where-Klausel in "Where RN> N" mit N> = 1 ändern. .

4) Fügte das Summenpartitionsfeld der CTE-Abfrage hinzu, die jede Zeile mit den Nummernzeilen in der Gruppe markiert. Um also Zeilen mit Duplikaten auszuwählen, einschließlich des ersten Elements, verwenden Sie "WHERE cnt> 1".

1
Darrel Lee

Um die beste Leistung zu erzielen, habe ich Folgendes geschrieben:
(siehe Ausführungsplan)

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
);
0
Enguerrand JORE

lösung:

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
);
0
sandeep gupta
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;
0
Ashish sinha