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 ?

352voto

Bill the Lizard Points 147311

Utilisez le rowid pseudo-colonne.

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

Donde column1 , column2 y column3 constituent la clé d'identification de chaque enregistrement. Vous pouvez dresser la liste de toutes vos colonnes.

7 votes

+1 Je devais trouver deux numéros de téléphone en double dans plus de 12 000 enregistrements. J'ai changé le DELETE en SELECT et cela les a trouvés en quelques secondes. J'ai gagné une tonne de temps, merci.

3 votes

Cette approche n'a pas fonctionné pour moi. Je ne sais pas pourquoi. Lorsque j'ai remplacé "DELETE" par "SELECT *", j'ai obtenu les lignes que je voulais supprimer, mais lorsque j'ai exécuté "DELETE", le processus s'est arrêté indéfiniment.

0 votes

Le mien est aussi soit suspendu, soit en train de s'exécuter extrêmement longtemps. Il fonctionne depuis environ 22 heures et est toujours en cours. La table a 21M d'enregistrements.

17voto

Dead Programmer Points 5428

Desde Demandez à 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);

(correction de la parenthèse manquante)

1 votes

Parenthèse manquante dans la déclaration. Je suppose qu'elle devrait être à la fin ?

15voto

Mark Points 363

Desde DevX.com :

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

Où colonne1, colonne2, etc. est la clé que vous voulez utiliser.

13voto

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

8voto

DoOrDie Points 275

Solution 1)

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

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

Solution 3)

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

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