sql >> Database >  >> RDS >> Mysql

Als ik een MySQL-tabel heb met meerdere dezelfde kolomwaarden, hoe verwijder ik dan op twee na alle meest recente vermeldingen?

Dit kan een oplossing zijn voor uw probleem.

Aangezien er echter geen datum-tijdkolom is, ga ik ervan uit dat de id-kolom de primaire sleutel is. En het is Auto_increment . Dus mijn veronderstelling is dat hoe groter het getal, hoe nieuwer het record. (het zou waar moeten zijn, tenzij je wat oude data dumps in de tabel had)

Zorg ervoor dat u een back-up van uw gegevens maakt voordat u ze verwijdert, omdat u hierdoor permanent gegevens kwijtraakt. Nog beter, je kunt een kopie van de huidige tabel maken in een andere tabel en aan de nieuwe tabel werken om ervoor te zorgen dat de onderstaande logica correct is. Wijzig vervolgens de vragen die ik hieronder heb om te lezen van tbl_new in plaats daarvan op tbl

je kunt je tabel dupliceren via iets als

CREATE TABLE tbl_new LIKE tbl;

Ik heb opmerkingen achtergelaten voor elke vraag

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

als dit een eenmalige opschoningstaak is, zou u de query's vanaf de console moeten kunnen uitvoeren. maar als u op zoek bent naar een rekruteringsbaan, moet u waarschijnlijk deze code nemen en in een procedure plaatsen.

Opmerking:hier gebruik ik MEMORY TIJDELIJKE tabellen voor betere prestaties. U kunt een probleem tegenkomen met de melding "Tabel is vol" dit komt omdat u te veel records heeft. dan kun je de waarde max_heap_table_size voor de sessie verhogen, zoiets als

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

Dit geeft u uw huidige waarde

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


  1. Scans van toewijzingsorders

  2. Opnieuw verbinding maken op MySQL-server is verdwenen

  3. Automatisch verhogen van de 'id'-waarde bij het invoegen in sqlite

  4. Aanroepnotatie voor PL/SQL-subroutines in Oracle Database