Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Se eu tiver uma tabela MySQL com vários valores de coluna iguais, como excluo todas as entradas mais recentes, exceto duas?


Esta pode ser uma solução para o seu problema.

No entanto, como não há coluna de data e hora, estou assumindo que a coluna id é a chave primária. E é Auto_increment . Então, minha suposição é que quanto maior o número, mais novo o registro. (deve ser verdade, a menos que você tenha alguns despejos de dados antigos na tabela)

Certifique-se de fazer backup de seus dados antes de excluir, pois isso causará a perda permanente de dados. Melhor ainda, você pode fazer uma cópia da tabela atual em uma tabela diferente e trabalhar na nova tabela para garantir que a lógica abaixo esteja correta. Em seguida, altere as consultas que tenho abaixo para ler de tbl_new em vez disso em tbl

você pode duplicar sua tabela através de algo como
CREATE TABLE tbl_new LIKE tbl;

Deixei comentários 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);

se este for um trabalho de limpeza único, você poderá executar as consultas no console. mas se você estiver procurando por um trabalho de recrutamento, provavelmente deve pegar esse código e colocá-lo em um procedimento.

Obs:aqui estou usando tabelas MEMORY TEMPORARY para melhor desempenho. Você pode encontrar um problema que diz "A tabela está cheia" isso ocorre porque você tem muitos registros. então você pode aumentar o valor max_heap_table_size para a sessão algo 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

Isso lhe dará seu valor atual
SELECT VARIABLES LIKE 'max_heap_table_size';
SELECT VARIABLES LIKE 'tmp_table_size';