U moet dergelijke vragen in principe in opgeslagen procedures vanwege enkele beperkingen op LIMIT . U kunt geen subselecties of variabelen gebruiken in gewone sql. In opgeslagen procedures kunt u variabelen gebruiken.
Dit werkt, helaas kan ik het niet laten zien in sqlfiddle omdat ze beperkte ondersteuning lijken te hebben voor opgeslagen procedures.
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();
Uitwerking van geclusterde InnoDB-indexen
Na discussies in een van de andere antwoorden met @fthiella heb ik besloten wat uit te leggen over hoe dit kan werken.
Een tabel die InnoDB als engine gebruikt, heeft altijd een geclusterde index. Altijd. Het is hun manier waarop gegevens worden opgeslagen in InnoDB en het is op geen enkele manier mogelijk om een tabel te maken zonder een geclusterde index.
InnoDB kiest de primaire sleutel als er een of de eerste unieke index is waarbij alle kolommen zijn ingesteld op niet null. Als zo'n index niet bestaat, maakt InnoDB een verborgen kolom met een rij-ID. Deze rij-ID werkt op dezelfde manier als auto-increment en als het helpt om het te zien als een onzichtbare kolom met auto-increment, vind ik dat prima.
Verder zal InnoDB rijen retourneren volgens de gebruikte index. Het zal altijd een index gebruiken (de enige manier om gegevens op te halen is door een secundaire index, de geclusterde index of een combinatie te gebruiken), dus in het geval dat er geen expliciet gemaakte indexen zijn, worden rijen geretourneerd door de verborgen geclusterde index.
Dit betekent dat een query op een tabel zonder primaire sleutel en zonder unieke indexen waarbij alle kolommen zijn ingesteld op niet null en geen ORDER BY, rijen retourneert in de volgorde waarin ze zijn ingevoegd.
Dit is het geval voor deze vraag en de basis voor de mijne en vele andere antwoorden.
Ik wil niet zeggen dat dit een goede manier is om met de gegevens te werken. Hier zijn enkele dingen waar u aan moet denken voordat u deze oplossing gebruikt:
- Als er ooit een index wordt gemaakt die kan worden gebruikt als een geclusterde index, wordt de tabel herschreven om die index te gebruiken en door dit te doen, worden de gegevens op schijf geordend. Als de index later wordt verwijderd, gaat de oorspronkelijke invoegvolgorde verloren en kan niet worden opgehaald.
- Als een index wordt gemaakt, zelfs als deze niet uniek is, kan deze worden gekozen door de optimizer om te gebruiken en worden de rijen in plaats daarvan op die index geordend.
Dit alles is gedocumenteerd en voor 5.5 zijn dit de 3e opsommingstekens op deze pagina