173 votes

Suppression des lignes en double d'une table dans Oracle

Je suis en train de tester quelque chose dans Oracle et j'ai rempli une table avec quelques données échantillons, mais au cours du processus, j'ai accidentellement chargé des enregistrements en double, de sorte que je ne peux pas créer de clé primaire en utilisant certaines des colonnes.

Comment puis-je supprimer toutes les lignes en double et n'en laisser qu'une seule ?

1voto

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

1voto

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

1voto

Enguerrand JORE Points 21

Pour une meilleure performance, voici ce que j'ai écrit :
(voir plan d'exécution)

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

1voto

Rakesh Roshan Points 11

Vérifiez les scripts ci-dessous -

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;    

Vous verrez ici 6 enregistrements.
4.exécuter la requête ci-dessous -

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;

Vous verrez que les enregistrements en double ont été supprimés.
J'espère que cela résoudra votre problème. Merci :)

1voto

Darrel Lee Points 226

Je n'ai pas vu de réponses qui utilisent les expressions courantes des tableaux et les fonctions des fenêtres. C'est ce que je trouve le plus facile à utiliser.

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

Quelques points à noter :

1) Nous vérifions uniquement les doublons dans les champs de la clause de partition.

2) Si vous avez une raison de choisir un duplicata plutôt que d'autres, vous pouvez utiliser une clause order by pour que cette ligne ait un row_number() = 1.

3) Vous pouvez modifier le nombre de doublons conservés en changeant la clause where finale en "Where RN > N" avec N >= 1 (je pensais que N = 0 supprimerait toutes les lignes qui ont des doublons, mais cela ne ferait que supprimer toutes les lignes).

4) Ajout du champ de partition Sum dans la requête CTE qui marquera chaque ligne avec le nombre de lignes dans le groupe. Donc pour sélectionner les lignes avec des doublons, y compris le premier élément, utilisez "WHERE cnt > 1".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X