[sql] SQL query: Delete all records from the table except latest N?

To delete all the records except te last N you may use the query reported below.

It's a single query but with many statements so it's actually not a single query the way it was intended in the original question.

Also you need a variable and a built-in (in the query) prepared statement due to a bug in MySQL.

Hope it may be useful anyway...

nnn are the rows to keep and theTable is the table you're working on.

I'm assuming you have an autoincrementing record named id

SELECT @ROWS_TO_DELETE := COUNT(*) - nnn FROM `theTable`;
SELECT @ROWS_TO_DELETE := IF(@ROWS_TO_DELETE<0,0,@ROWS_TO_DELETE);
PREPARE STMT FROM "DELETE FROM `theTable` ORDER BY `id` ASC LIMIT ?";
EXECUTE STMT USING @ROWS_TO_DELETE;

The good thing about this approach is performance: I've tested the query on a local DB with about 13,000 record, keeping the last 1,000. It runs in 0.08 seconds.

The script from the accepted answer...

DELETE FROM `table`
WHERE id NOT IN (
  SELECT id
  FROM (
    SELECT id
    FROM `table`
    ORDER BY id DESC
    LIMIT 42 -- keep this many records
  ) foo
);

Takes 0.55 seconds. About 7 times more.

Test environment: mySQL 5.5.25 on a late 2011 i7 MacBookPro with SSD