基本的に、このようなクエリをストアドプロシージャ> 制限 にいくつかの制限があるため 。プレーンSQLではサブ選択または変数を使用できません。ストアドプロシージャでは、変数を使用できます。
これは機能しますが、残念ながらsqlfiddle には表示できません。 ストアドプロシージャのサポートが制限されているようです。
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();
InnoDBクラスター化インデックスの詳細
@fthiellaと他の回答のいずれかで話し合った後、これがどのように機能するかについて詳しく説明することにしました。
InnoDBをエンジンとして使用するテーブルには、常にクラスター化インデックスがあります。いつも。これは、データがInnoDBに格納される方法であり、クラスター化インデックスなしでテーブルを作成することは決して不可能です。
すべての列がnull以外に設定された1つまたは最初の一意のインデックスがある場合、InnoDBは主キーを選択します。そのようなインデックスが存在しない場合、InnoDBは行IDを持つ非表示の列を作成します。この行IDは自動インクリメントと同様に機能し、自動インクリメントの非表示の列と見なすのに役立つ場合は、それで問題ないと思います。
さらに、InnoDBは使用されたインデックスに従って行を返します。常に何らかのインデックスを使用します(データを取得する唯一の方法は、セカンダリインデックス、クラスター化インデックス、またはその組み合わせのいずれかを使用することです)。したがって、明示的に作成されたインデックスがない場合、行は非表示のクラスター化インデックスによって返されます。
これは、主キーがなく、すべての列がnull以外に設定され、ORDER BYがない一意のインデックスがないテーブルに対するクエリは、挿入された順序で行を返すことを意味します。
これは、この質問と私のベースおよび他の多くの回答の場合です。
これがデータを操作するための良い方法であると言うつもりはありません。このソリューションを使用する前に考慮すべきことがいくつかあります。
- クラスター化されたインデックスとして使用できるインデックスが作成された場合、そのインデックスを使用するようにテーブルが書き換えられ、そうすることでディスク上のデータが並べ替えられます。後でインデックスが削除されると、元の挿入順序が失われ、取得できなくなります。
- インデックスが作成された場合、それが一意でなくても、使用するオプティマイザーによって選択され、代わりにそのインデックスによって行が並べ替えられます。
これはすべて文書化されており、5.5の場合、このページ