Você basicamente precisa colocar essas consultas em procedimentos armazenados devido a algumas limitações em LIMIT . Você não pode usar subseleções ou variáveis em sql simples. Em procedimentos armazenados, você pode usar variáveis.
Isso funciona, infelizmente não posso mostrá-lo em sqlfiddle porque eles parecem ter suporte limitado para procedimentos armazenados.
drop procedure if exists all_but_3;
delimiter //
create procedure all_but_3()
begin
declare v_max bigint unsigned default ~0;
select * from your_table limit 3, v_max;
end//
delimiter ;
drop procedure if exists last_3;
delimiter //
create procedure last_3()
begin
declare v_max bigint;
declare v_mid bigint;
select count(*) from your_table into v_max;
set v_mid := v_max - 3;
select * from your_table limit v_mid, v_max;
end//
delimiter ;
call all_but_3();
call last_3();
Elaboração em índices clusterizados InnoDB
Após discussões em uma das outras respostas com @fthiella, decidi elaborar algumas sobre como isso pode funcionar.
Uma tabela usando o InnoDB como mecanismo sempre terá um índice clusterizado. Sempre. É assim que os dados são armazenados no InnoDB e não é de forma alguma possível criar uma tabela sem um índice clusterizado.
O InnoDB escolherá a chave primária se houver um ou o primeiro índice exclusivo com todas as colunas definidas como não nulas. Se esse índice não existir, o InnoDB criará uma coluna oculta com um id de linha. Esse id de linha funciona de maneira semelhante ao incremento automático e, se ajudar a pensar nisso como uma coluna invisível com incremento automático, acho que está tudo bem.
Além disso, o InnoDB retornará linhas de acordo com o índice usado. Ele sempre usará algum índice (a única maneira de recuperar dados é usar um índice secundário, o índice clusterizado ou uma combinação), portanto, no caso de não haver índices criados explicitamente, as linhas são retornadas pelo índice clusterizado oculto.
Isso significa que uma consulta em uma tabela sem chave primária e sem índices exclusivos com todas as colunas definidas como não nulas e sem ORDER BY retornará linhas na ordem em que foram inseridas.
Este é o caso desta pergunta e a base para a minha e muitas outras respostas.
Não quero dizer que esta é uma boa maneira de trabalhar com os dados. Aqui estão algumas coisas que você deve pensar antes de usar esta solução:
- Se um índice que pode ser usado como índice clusterizado for criado, a tabela será reescrita para usar esse índice e, assim, ordenar os dados no disco. Se o índice for descartado posteriormente, a ordem de inserção original será perdida e não poderá ser recuperada.
- Se um índice for criado, mesmo que não seja exclusivo, ele poderá ser escolhido pelo otimizador para ser usado e as linhas serão ordenadas por esse índice.
Tudo isso está documentado e, para 5.5, é o terceiro ponto em esta página