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
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
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
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 )
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!
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.
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.
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.
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
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
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])
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)
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é.
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
)
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.
supprimer le sous de (sélectionner ROW_NUMBER () OVer (partition par ordre empid par empid) cnt de l'employé) sous où sub.cnt> 1