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
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
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 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 )
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!
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.
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.
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.
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
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
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.
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.
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)
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
)
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])
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
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
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.