Supprimer des enregistrements dupliqués d'une table SQL sans clé primaire

j'ai le tableau ci-dessous avec les dossiers

create table employee
(
 EmpId number,
 EmpName varchar2(10),
 EmpSSN varchar2(11)
);

insert into employee values(1, 'Jack', '555-55-5555');
insert into employee values (2, 'Joe', '555-56-5555');
insert into employee values (3, 'Fred', '555-57-5555');
insert into employee values (4, 'Mike', '555-58-5555');
insert into employee values (5, 'Cathy', '555-59-5555');
insert into employee values (6, 'Lisa', '555-70-5555');
insert into employee values (1, 'Jack', '555-55-5555');
insert into employee values (4, 'Mike', '555-58-5555');
insert into employee values (5, 'Cathy', '555-59-5555');
insert into employee values (6 ,'Lisa', '555-70-5555');
insert into employee values (5, 'Cathy', '555-59-5555');
insert into employee values (6, 'Lisa', '555-70-5555');

Je n'ai pas de clé primaire dans ce tableau .Mais j'ai déjà les enregistrements ci-dessus dans ma table. Je veux supprimer les enregistrements dupliqués qui ont la même valeur dans les champs EmpId et EmpSSN.

Ex: Idem 5

quelqu'un Peut-il m'aider à encadrer une requête pour supprimer ces doublons

Merci d'avance

46
demandé sur abatishchev 2009-06-12 11:12:06

17 réponses

ajouter une clé primaire (code ci-dessous)

exécuter le bon supprimer (code ci-dessous)

voyez pourquoi vous ne voulez pas garder cette clé primaire.


en supposant MSSQL ou compatible:

ALTER TABLE Employee ADD EmployeeID int identity(1,1) PRIMARY KEY;

WHILE EXISTS (SELECT COUNT(*) FROM Employee GROUP BY EmpID, EmpSSN HAVING COUNT(*) > 1)
BEGIN
    DELETE FROM Employee WHERE EmployeeID IN 
    (
        SELECT MIN(EmployeeID) as [DeleteID]
        FROM Employee
        GROUP BY EmpID, EmpSSN
        HAVING COUNT(*) > 1
    )
END
52
répondu cjk 2010-07-16 07:47:20

c'est très simple. J'ai essayé dans SQL Server 2008

DELETE SUB FROM
(SELECT ROW_NUMBER() OVER (PARTITION BY EmpId, EmpName, EmpSSN ORDER BY EmpId) cnt
 FROM Employee) SUB
WHERE SUB.cnt > 1
69
répondu Anjib Rajkhowa 2014-06-16 18:03:40

utilisez le numéro de ligne pour distinguer les enregistrements en double. Conserver le numéro de la première ligne pour un EmpID / EmpSSN et supprimer le reste:

    DELETE FROM Employee a
     WHERE ROW_NUMBER() <> ( SELECT MIN( ROW_NUMBER() )
                               FROM Employee b
                              WHERE a.EmpID  = b.EmpID
                                AND a.EmpSSN = b.EmpSSN )
22
répondu Paul Morgan 2010-07-20 01:33:31
With duplicates

As
(Select *, ROW_NUMBER() Over (PARTITION by EmpID,EmpSSN Order by EmpID,EmpSSN) as Duplicate From Employee)

delete From duplicates

Where Duplicate > 1 ;

ceci mettra à jour la Table et supprimera tous les doublons de la Table!

9
répondu Nirav Parikh 2011-12-06 16:44:34
select distinct * into newtablename from oldtablename

maintenant, le newtablename n'aura aucun enregistrement en double.

il suffit de changer le nom de la table ( newtablename ) en appuyant sur F2 dans l'Explorateur d'objets dans sql server.

7
répondu naga vara prasad 2012-10-20 01:38:50

vous pouvez créer une table temporaire #tempemployee contenant une select distinct de votre table employee . Puis delete from employee . Puis insert into employee select from #tempemployee .

comme Josh l'a dit - même si vous connaissez les duplicates , les supprimer sera impossible car vous ne pouvez pas réellement vous référer à un enregistrement spécifique si c'est une copie exacte d'un autre enregistrement.

6
répondu Daren Thomas 2009-06-12 07:16:34

Code

DELETE DUP 
FROM 
( 
    SELECT ROW_NUMBER() OVER (PARTITION BY Clientid ORDER BY Clientid ) AS Val 
    FROM ClientMaster 
) DUP 
WHERE DUP.Val > 1

explication

utilisez une requête interne pour construire une vue sur la table qui inclut un champ basé sur Row_Number() , partitionné par ces colonnes que vous souhaitez être unique.

Supprimer des résultats de cette requête interne, en sélectionnant tout ce qui n'a pas un numéro de ligne de 1; c.-à-d. les doublons; pas l'original.

la clause order by de la fonction de fenêtre row_number est nécessaire pour une syntaxe valide; Vous pouvez mettre n'importe quel nom de colonne ici. Si vous souhaitez modifier des résultats est considérée comme un doublon (par exemple, de garder les plus anciennes ou plus récentes, etc), la colonne(s) utilisé ici n'importe; c'est à dire que vous voulez spécifier l'ordre telles que l'enregistrement que vous souhaitez conserver viendra d'abord dans le résultat.

3
répondu kamz kamarajan 2017-04-07 11:39:31

si vous ne voulez pas créer une nouvelle clé primaire, vous pouvez utiliser la commande supérieure dans SQL Server:

declare @ID int
while EXISTS(select count(*) from Employee group by EmpId having count(*)> 1)
begin
    select top 1 @ID = EmpId
    from Employee 
    group by EmpId
    having count(*) > 1

    DELETE TOP(1) FROM Employee WHERE EmpId = @ID
end
2
répondu Joe 2010-06-02 21:30:41

son utilisation facile ci-dessous requête

WITH Dups AS
(
  SELECT col1,col2,col3,
ROW_NUMBER() OVER(PARTITION BY col1,col2,col3 ORDER BY (SELECT 0)) AS rn
 FROM mytable
)
DELETE FROM Dups WHERE rn > 1
1
répondu Abhishek Jaiswal 2016-09-19 10:20:10

Je ne suis pas un expert en SQL. Je suis sûr que tu auras une meilleure réponse bientôt. Voici comment vous pouvez trouver les enregistrements dupliqués.

select t1.empid, t1.empssn, count(*)
from employee as t1 
inner join employee as t2 on (t1.empid=t2.empid and t1.empssn = t2.empssn)
group by t1.empid, t1.empssn
having count(*) > 1

les supprimer sera plus délicat parce qu'il n'y a rien dans les données que vous pourriez utiliser dans une déclaration Supprimer pour différencier les doublons. Je soupçonne que la réponse impliquera row_number () ou l'ajout d'une colonne identity.

0
répondu Josh 2009-06-12 07:18:02
create unique clustered index Employee_idx
on Employee ( EmpId,EmpSSN )
with ignore_dup_key

Vous pouvez supprimer l'index si vous n'en avez pas besoin.

0
répondu Sudhir 2012-07-06 11:35:19

non ID , pas de rowcount() ou pas temp table nécessaire....

WHILE 
  (
     SELECT  COUNT(*) 
     FROM TBLEMP  
     WHERE EMPNO 
            IN (SELECT empno  from tblemp group by empno having count(empno)>1)) > 1 


DELETE top(1)  
FROM TBLEMP 
WHERE EMPNO IN (SELECT empno  from tblemp group by empno having count(empno)>1)
0
répondu Ashish Sahu 2013-04-14 06:25:05

il y a deux colonnes dans la table A ID et nom où les noms se répètent avec des ID différents afin que vous puissiez utiliser cette requête: . .

DELETE FROM dbo.tbl1
WHERE id NOT IN (
     Select MIN(Id) AS namecount FROM tbl1
     GROUP BY Name
)
0
répondu user2497372 2013-06-18 13:55:14

avoir une table de base de données sans clé primaire est vraiment et dira extrêmement mauvaise pratique...donc après avoir ajouté un (ALTER TABLE)

exécutez ceci jusqu'à ce que vous ne voyez plus aucun enregistrement dupliqué (c'est le but d'avoir le compte)

DELETE FROM [TABLE_NAME] WHERE [Id] IN 
(
    SELECT MAX([Id])
    FROM [TABLE_NAME]
    GROUP BY [TARGET_COLUMN]
    HAVING COUNT(*) > 1
)


SELECT MAX([Id]),[TABLE_NAME], COUNT(*) AS dupeCount
FROM [TABLE_NAME]
GROUP BY [TABLE_NAME]
HAVING COUNT(*) > 1

MAX ([Id]) fera supprimer les derniers enregistrements (ceux ajoutés après la première création) dans le cas où vous voulez le sens opposé que dans le cas de la nécessité de supprimer les premiers enregistrements et de laisser le dernier enregistrement insérée veuillez utiliser MIN ([Id])

0
répondu d1jhoni1b 2014-07-19 04:08:45
select t1.* from employee t1, employee t2 where t1.empid=t2.empid and t1.empname = t2.empname and t1.salary = t2.salary
group by t1.empid, t1.empname,t1.salary having count(*) > 1
-1
répondu Freelancer 2013-06-03 09:38:35
DELETE FROM 'test' 
USING 'test' , 'test' as vtable
WHERE test.id>vtable.id and test.common_column=vtable.common_column  

en utilisant ceci nous pouvons supprimer les enregistrements en double

-2
répondu jayaram.pagoti 2011-11-07 12:53:21
ALTER IGNORE TABLE test
           ADD UNIQUE INDEX 'test' ('b'); 

@ ici 'b' est le nom de la colonne pour unicité, @ ici "test" est le nom de l'index.

-3
répondu jayaram.pagoti 2012-08-01 09:27:35