Você não pode excluir os registros dessa maneira, o principal problema é que você não pode usar uma subconsulta para especificar o valor de uma cláusula LIMIT.
Isso funciona (testado no MySQL 5.0.67):
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
);
A subconsulta intermediária é requerido. Sem ele, teríamos dois erros:
- Erro SQL (1093):você não pode especificar a tabela de destino 'tabela' para atualização na cláusula FROM - O MySQL não permite que você faça referência à tabela que está excluindo de dentro de uma subconsulta direta.
- Erro SQL (1235):Esta versão do MySQL ainda não suporta 'LIMIT &IN/ALL/ANY/SOME subconsulta' - Você não pode usar a cláusula LIMIT em uma subconsulta direta de um operador NOT IN.
Felizmente, usar uma subconsulta intermediária nos permite contornar essas duas limitações.
Nicole apontou que essa consulta pode ser otimizada significativamente para determinados casos de uso (como este). Eu recomendo ler essa resposta também para ver se ele se encaixa no seu.