mysql doppelte Datenlöschung
-
23-09-2019 - |
Frage
Das zeigt mir alle Vornamen und Nachnamen, die genau zwei Einträge haben, die identisch sind
SELECT `firstname`,`lastname`,COUNT(*) AS Count
FROM `people`
GROUP BY `firstname`,`lastname`
HAVING Count = 2
Wie kann ich dies in eine DELETE FROM WHERE-Anweisung mit einem LIMIT nur einer von jedem der Einträge zu entfernen und das andere lassen.
okay, dies scheint Weg, um technisch Ich bin gerade jetzt tue es in einem PHP-while-Schleife
Lösung
Sie können eine Tabelle mit 1 Datensatz jeder der Duplikate erstellen. Dann werden alle dup Datensätze aus dem Menschen Tabelle löschen und dann wieder einsetzen dup records
-- 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;
Andere Tipps
Wenn Sie einen Primärschlüssel, wie id haben, können Sie tun:
delete from people
where id not in
(
select minid from
(select min(id) as minid from people
group by firstname, lastname) as newtable
)
Der Unterabfrage select min(id)...
Bit wird immer Sie die einzigartigen (basierend auf id) Zeilen für einen bestimmten Vornamen, Nachnamen Kombination; und dann sind Löschen Sie alle anderen Zeilen, das heißt Ihre Duplikate. Sie benötigen eine Unterabfrage aufgrund eines Fehlers in mysql wickeln, sonst könnten wir tun:
delete from people
where id not in
(
select min(id) as minid from people
group by firstname, lastname
)
besser wäre:
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
die Unterabfrage zu vermeiden.
Erstellen Sie eine neue Tabelle, und fügen Sie einen eindeutigen Schlüssel auf (Vorname, Nachname). Dann legen Sie die Zeilen in der alten Tabelle in die neue Tabelle. Dann werden die Tabellen umbenennen.
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)