Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wenn ich eine MySQL-Tabelle mit mehreren gleichen Spaltenwerten habe, wie lösche ich dann alle bis auf zwei der neuesten Einträge?

Dies könnte eine Lösung für Ihr Problem sein.

Da es jedoch keine Datum-Uhrzeit-Spalte gibt, gehe ich davon aus, dass die ID-Spalte der Primärschlüssel ist. Und es ist Auto_increment . Meine Annahme ist also, je größer die Zahl, desto neuer der Datensatz. (Es sollte wahr sein, es sei denn, Sie hatten einige alte Datendumps in der Tabelle)

Stellen Sie sicher, dass Sie Ihre Daten sichern, bevor Sie sie löschen, da dies zu einem dauerhaften Datenverlust führt. Noch besser, Sie können eine Kopie der aktuellen Tabelle in eine andere Tabelle erstellen und an der neuen Tabelle arbeiten, um sicherzustellen, dass die folgende Logik korrekt ist. Ändern Sie dann die Abfragen, die ich unten habe, um von tbl_new zu lesen stattdessen auf tbl

Sie können Ihre Tabelle über so etwas wie

duplizieren
CREATE TABLE tbl_new LIKE tbl;

Ich habe Kommentare zu jeder Anfrage hinterlassen

DROP TEMPORARY TABLE IF EXISTS keepers1, keepers2, keepers_all;
-- get the #1 top records
CREATE TEMPORARY TABLE keepers1 (KEY(id)) ENGINE=MEMORY AS
SELECT fid, bid, dec_a, varc_a, varc_b, dec_b, varc_c, MAX(id) AS id
FROM tbl
GROUP BY fid, bid, dec_a, varc_a, varc_b, dec_b, varc_c;

-- get the #2 top records
CREATE TEMPORARY TABLE keepers2 AS
SELECT fid, bid, dec_a, varc_a, varc_b, dec_b, varc_c, MAX(id) AS id
FROM tbl AS k
WHERE NOT EXISTS (SELECT 1 FROM keepers1 WHERE id = k.id)
GROUP BY fid, bid, dec_a, varc_a, varc_b, dec_b, varc_c;


-- create a temp table where you have all he ids that you want to keep
CREATE TEMPORARY TABLE keepers_all (KEY(id)) ENGINE=MEMORY AS
SELECT id FROM keepers1
UNION ALL
SELECT id FROM keepers2;


-- delete all records that you don't want to keep
DELETE k.* FROM tbl AS k WHERE NOT EXISTS (SELECT 1 FROM keepers_all WHERE id = k.id);

Wenn es sich um einen einmaligen Bereinigungsjob handelt, sollten Sie die Abfragen von der Konsole aus ausführen können. aber wenn Sie nach einem Rekrutierungsjob suchen, sollten Sie wahrscheinlich diesen Code nehmen und ihn in ein Verfahren einfügen.

Hinweis:Hier verwende ich MEMORY TEMPORARY-Tabellen für eine bessere Leistung. Sie können auf ein Problem stoßen, das besagt:"Table is Full" Dies liegt daran, dass Sie zu viele Datensätze haben. dann können Sie den Wert max_heap_table_size für die Sitzung erhöhen, etwa

SET SESSION tmp_table_size = 1024 * 1024 * 1024 * 2; -- this will set it to 2G
SET SESSION max_heap_table_size = 1024 * 1024 * 1024 * 2; -- this will set it to 2G

Dadurch erhalten Sie Ihren aktuellen Wert

SELECT VARIABLES LIKE 'max_heap_table_size';
SELECT VARIABLES LIKE 'tmp_table_size';