mysql suppression de données en double
-
23-09-2019 - |
Question
Cela me montre tous les prénoms et noms de famille qui ont exactement deux entrées identiques
SELECT `firstname`,`lastname`,COUNT(*) AS Count
FROM `people`
GROUP BY `firstname`,`lastname`
HAVING Count = 2
Comment puis-je en faire un SUPPRIMER DE WHERE avec une limite à ne supprimer l'un de chacune des entrées et laisser l'autre.
ok cela semble être moyen de technique je suis juste aller le faire dans un php while
La solution
Vous pouvez créer une table avec 1 enregistrement de chacune des doublons. Ensuite, supprimez tous les enregistrements de la table dup personnes, puis ré-insérer les enregistrements dup
-- Setup for example
create table people (fname varchar(10), lname varchar(10));
insert into people values ('Bob', 'Newhart');
insert into people values ('Bob', 'Newhart');
insert into people values ('Bill', 'Cosby');
insert into people values ('Jim', 'Gaffigan');
insert into people values ('Jim', 'Gaffigan');
insert into people values ('Adam', 'Sandler');
-- Show table with duplicates
select * from people;
-- Create table with one version of each duplicate record
create table dups as
select distinct fname, lname, count(*)
from people group by fname, lname
having count(*) > 1;
-- Delete all matching duplicate records
delete people from people inner join dups
on people.fname = dups.fname AND
people.lname = dups.lname;
-- Insert single record of each dup back into table
insert into people select fname, lname from dups;
-- Show Fixed table
select * from people;
Autres conseils
si vous avez une clé primaire, comme l'ID, vous pouvez faire:
delete from people
where id not in
(
select minid from
(select min(id) as minid from people
group by firstname, lastname) as newtable
)
Le bit select min(id)...
de sous-requête est vous obtenir les lignes uniques (basé sur id) pour un prenom donné, combinaison lastname; puis vous supprimez toutes les autres lignes, à savoir vos doublons. Vous devez envelopper votre sous-requête en raison d'un bogue dans MySQL, sinon nous pourrions faire:
delete from people
where id not in
(
select min(id) as minid from people
group by firstname, lastname
)
mieux serait:
delete people from
people left outer join
(
select min(id) as minid from people
group by firstname, lastname
) people_grouped
on people.first_name = people_grouped.first_name
and people.last_name = people_grouped.last_name
and people_grouped.id is null
pour éviter la sous-requête.
Créer une nouvelle table et ajouter une clé unique (nom, prénom). Ensuite, insérez les lignes de vieille table dans la nouvelle table. Ensuite, renommer les tables.
mysql> select * from t;
+-----------+----------+
| firstname | lastname |
+-----------+----------+
| A | B |
| A | B |
| X | Y |
+-----------+----------+
3 rows in set (0.00 sec)
mysql> create table t2 like t;
Query OK, 0 rows affected (0.00 sec)
mysql> alter table t2 add unique key name(firstname,lastname);
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> insert ignore into t2 select * from t;
Query OK, 2 rows affected (0.00 sec)
Records: 3 Duplicates: 1 Warnings: 0
mysql> select * from t2;
+-----------+----------+
| firstname | lastname |
+-----------+----------+
| A | B |
| X | Y |
+-----------+----------+
2 rows in set (0.01 sec)