sql >> Base de Datos >  >> RDS >> Mysql

Si tengo una tabla MySQL con varios valores de columna iguales, ¿cómo elimino todas menos dos de las entradas más recientes?

Esta puede ser una solución para su problema.

Sin embargo, dado que no hay una columna de fecha y hora, asumo que la columna de identificación es la clave principal. Y es Auto_increment . Así que mi suposición es que cuanto mayor sea el número, más nuevo será el registro. (debería ser cierto a menos que haya volcado algunos datos antiguos en la tabla)

Asegúrese de hacer una copia de seguridad de sus datos antes de eliminarlos, ya que esto provocará una pérdida permanente de datos. Aún mejor, puede hacer una copia de la tabla actual en una tabla diferente y trabajar en la nueva tabla para asegurarse de que la lógica a continuación sea correcta. Luego cambie las consultas que tengo a continuación para leer desde tbl_new en lugar de tbl

puedes duplicar tu tabla a través de algo como

CREATE TABLE tbl_new LIKE tbl;

He dejado comentarios para cada consulta

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);

si se trata de un trabajo de limpieza único, debería poder ejecutar las consultas desde la consola. pero si está buscando un trabajo de reclutamiento, probablemente debería tomar este código y ponerlo en un procedimiento.

Nota:aquí estoy usando tablas MEMORY TEMPORARY para un mejor rendimiento. Puede encontrarse con un problema que diga "Table is Full" esto se debe a que tiene demasiados registros. entonces puede aumentar el valor max_heap_table_size para la sesión, algo así como

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

Esto le dará su valor actual

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