Dubbele rijen verwijderen uit tabel in Oracle

Ik test iets in Oracle en vulde een tabel met enkele voorbeeldgegevens, maar daarbij heb ik per ongeluk dubbele records geladen, dus nu kan ik geen primaire sleutel maken met behulp van enkele van de kolommen.

Hoe kan ik alle dubbele rijen verwijderen en er slechts één laten staan?


Antwoord 1, autoriteit 100%

Gebruik de rowidpseudokolom.

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

Waar column1, column2en column3de identificatiesleutel voor elk record vormen. U kunt al uw kolommen weergeven.


Antwoord 2, autoriteit 5%

Van Vraag het aan 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);

(het ontbrekende haakje gerepareerd)


Antwoord 3, autoriteit 4%

Van DevX.com:

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

Waarbij kolom1, kolom2, enz. de sleutel is die u wilt gebruiken.


Antwoord 4, autoriteit 4%

DELETE FROM tablename a
      WHERE a.ROWID > ANY (SELECT b.ROWID
                             FROM tablename b
                            WHERE a.fieldname = b.fieldname
                              AND a.fieldname2 = b.fieldname2)

Antwoord 5, autoriteit 2%

Oplossing 1)

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

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

Oplossing 3)

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

Antwoord 6, autoriteit 2%

maak tabel t2 als select distinct * from t1;


Antwoord 7

Je moet een klein pl/sql-blok maken met een cursor voor lus en de rijen verwijderen die je niet wilt behouden. Bijvoorbeeld:

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;

Antwoord 8

Om de duplicaten te selecteren kan alleen het query-formaat zijn:

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

Dus de juiste vraag volgens andere suggestie is:

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

Deze zoekopdracht bewaart het oudste record in de database voor de criteria die zijn gekozen in de WHERE CLAUSE.

Oracle Certified Associate (2008)


Antwoord 9

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

Antwoord 10

De snelste manier voor echt grote tafels

  1. Maak uitzonderingstabel met onderstaande structuur:
    exceptions_table

    ROW_ID ROWID
    OWNER VARCHAR2(30)
    TABLE_NAME VARCHAR2(30)
    CONSTRAINT VARCHAR2(30)
    
  2. Probeer een unieke beperking of primaire sleutel te maken die door de duplicaten wordt geschonden. Je krijgt een foutmelding omdat je duplicaten hebt. De uitzonderingentabel zal bevatten:
    de rowids voor de dubbele rijen.

    alter table add constraint
    unique --or primary key
    (dupfield1,dupfield2) exceptions into exceptions_table;
    
  3. Doe mee aan uw tafel met exceptions_table door rowid en verwijder dups

    delete original_dups where rowid in (select ROW_ID from exceptions_table);
    
  4. Als het aantal te verwijderen rijen groot is, maak dan een nieuwe tabel (met alle toewijzingen en indexen) anti-joining met exceptions_table door rowid en hernoem de originele tabel in original_dups tabel en hernoem new_table_with_no_dups in originele tabel

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

Antwoord 11

rowid-

. gebruiken

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

Self join-

. gebruiken

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

Antwoord 12

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

Antwoord 13

1. oplossing

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

2. oplossing

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

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

4. oplossing

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

Antwoord 14

5. oplossing

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

Antwoord 15

DELETE from table_name where rowid not in (select min(rowid) FROM table_name group by column_name);

en u kunt dubbele records ook op een andere manier verwijderen

DELETE from table_name a where rowid > (select min(rowid) FROM table_name b where a.column=b.column);

Antwoord 16

DELETE FROM tableName  WHERE ROWID NOT IN (SELECT   MIN (ROWID) FROM table GROUP BY columnname);

Antwoord 17

delete from dept
where rowid in (
     select rowid
     from dept
     minus
     select max(rowid)
     from dept
     group by DEPTNO, DNAME, LOC
);

Antwoord 18

Voor de beste prestaties, hier is wat ik schreef:
(zie uitvoeringsplan)

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

Antwoord 19

Controleer onderstaande scripts –

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;    

Je ziet hier 6 records.
4. voer onderstaande zoekopdracht uit –

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;

U zult zien dat dubbele records zijn verwijderd.
Hoop dat dit je vraag oplost.
Bedankt 🙂


Antwoord 20

Ik heb geen antwoorden gezien die algemene tabeluitdrukkingen en vensterfuncties gebruiken.
Dit vind ik het makkelijkst om mee te werken.

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

Iets om op te merken:

1) We controleren alleen op duplicatie van de velden in de partitieclausule.

2) Als u een reden heeft om één duplicaat te verkiezen boven andere, kunt u een order by-clausule gebruiken om ervoor te zorgen dat die rij row_number() = 1 heeft

3) U kunt het aantal behouden duplicaat wijzigen door de definitieve where-clausule te wijzigen in “Waar RN > N” met N >= 1 (ik dacht dat N = 0 alle rijen met duplicaten zou verwijderen, maar het zou verwijder gewoon alle rijen).

4) Het veld Sum-partitie toegevoegd aan de CTE-query die elke rij zal taggen met de nummerrijen in de groep. Dus om rijen met duplicaten te selecteren, inclusief het eerste item, gebruik “WHERE cnt > 1”.


Antwoord 21

Deze blogpostwas erg nuttig voor algemene gevallen:

Als de rijen volledig zijn gedupliceerd (alle waarden in alle kolommen kunnen kopieën hebben), zijn er geen kolommen om te gebruiken! Maar om er een te behouden, hebt u nog steeds een unieke identificatie nodig voor elke rij in elke groep.
Gelukkig heeft Oracle al iets dat je kunt gebruiken. De roeier.
Alle rijen in Oracle hebben een rowid. Dit is een fysieke zoeker. Dat wil zeggen, het geeft aan waar op schijf Oracle de rij opslaat. Dit is uniek voor elke rij. U kunt deze waarde dus gebruiken om kopieën te identificeren en te verwijderen. Vervang hiervoor min() door min(rowid) in de niet-gecorreleerde delete:

delete films
where  rowid not in (
  select min(rowid)
  from   films
  group  by title, uk_release_date
)

Antwoord 22

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;

Antwoord 23

oplossing:

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

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes