web-dev-qa-db-fra.com

Supprimer les enregistrements en double d'une table SQL sans clé primaire

J'ai le tableau ci-dessous avec les enregistrements ci-dessous

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 cette table. Mais j'ai déjà les enregistrements ci-dessus dans ma table. Je souhaite supprimer les enregistrements en double qui ont la même valeur dans les champs EmpId et EmpSSN.

Ex: Emp id 5

Quelqu'un peut-il m'aider à encadrer une requête pour supprimer ces enregistrements en double

Merci d'avance

50
Shyju

Ajouter une clé primaire (code ci-dessous)

Exécutez la suppression correcte (code ci-dessous)

Considérez POURQUOI vous ne souhaitez pas conserver 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
54
cjk

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
71
Anjib Rajkhowa

Utilisez le numéro de ligne pour différencier les enregistrements en double. Conservez le premier numéro de ligne pour un EmpID/EmpSSN et supprimez 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
Paul Morgan
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 ;

Cela mettra à jour le tableau et supprimera tous les doublons du tableau!

9
Nirav Parikh
select distinct * into newtablename from oldtablename

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

Modifiez simplement le nom de la table (newtablename) en appuyant sur F2 dans l'Explorateur d'objets sur le serveur SQL.

7
naga vara prasad

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

Comme l'a dit Josh - même si vous connaissez les doublons, les supprimer sera impossible car vous ne pouvez pas réellement faire référence à un enregistrement spécifique s'il s'agit d'un doublon exact d'un autre enregistrement.

6
Daren Thomas

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 comprend un champ basé sur Row_Number(), partitionné par les 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'est-à-dire 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 lequel des résultats est traité comme un doublon (par exemple, conserver le plus ancien ou le plus récent, etc.), alors la ou les colonnes utilisées ici importent; c'est-à-dire que vous souhaitez spécifier l'ordre de telle sorte que l'enregistrement que vous souhaitez conserver passe en premier dans le résultat.

3
kamz kamarajan

SON utilisation facile sous la 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
2
Abhishek Jaiswal

Si vous ne souhaitez pas créer de nouvelle clé primaire, vous pouvez utiliser la commande TOP 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
Joe

Avoir une table de base de données sans clé primaire est vraiment et dira une très mauvaise pratique ... donc après en avoir ajouté une (ALTER TABLE)

Exécutez ceci jusqu'à ce que vous ne voyiez plus d'enregistrements en double (c'est le but de HAVING COUNT)

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]) entraînera la suppression des derniers enregistrements (ceux ajoutés après la première création) au cas où vous souhaiteriez le contraire, ce qui signifie qu'en cas de suppression des premiers enregistrements et de laisser le dernier enregistrement inséré, utilisez MIN ([Id])

0
d1jhoni1b

no ID, no rowcount() or no 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
Ashish Sahu

Je ne suis pas un expert SQL alors soyez indulgent avec moi. Je suis sûr que vous obtiendrez une meilleure réponse assez tôt. Voici comment trouver les enregistrements en double.

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 car il n'y a rien dans les données que vous puissiez utiliser dans une instruction delete pour différencier les doublons. Je soupçonne que la réponse impliquera row_number () ou l'ajout d'une colonne d'identité.

0
Josh

il y a deux colonnes dans l'ID et le nom d'une table où les noms se répètent avec des ID différents, pour 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
user2497372
créer un index cluster unique Employee_idx 
 sur Employee (EmpId, EmpSSN) 
 avec ignore_dup_key

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

0
Sudhir

supprimer le sous de (sélectionner ROW_NUMBER () OVer (partition par ordre empid par empid) cnt de l'employé) sous où sub.cnt> 1

0
Sudhar P