Pervasive SQL(バージョン9.1)でページングを行う方法は?私は次のようなことをする必要があります:
//MySQL
SELECT foo FROM table LIMIT 10, 10
しかし、オフセットを定義する方法が見つかりません。
PSQLでテストされたクエリ:
select top n *
from tablename
where id not in(
select top k id
from tablename
)
すべてのn=レコードの数に対してuは一度にフェッチする必要があります。およびk=nの倍数(例:n = 5; k = 0,5,10,15、....)
ページングでは、現在のページ番号とページサイズ(およびいくつかの追加のフィルターパラメーター)を変数として渡すことができる必要がありました。select top@page_sizeはMSSQLでは機能しないため、一時テーブルまたは可変テーブルを作成して、各行の主キーにIDを割り当て、後で目的のページ番号とサイズでフィルタリングできるようにしました。
** GUID主キーまたは複合キーがある場合は、一時テーブルのオブジェクトIDをuniqueidentifierに変更するか、テーブルに追加のキー列を追加するだけでよいことに注意してください。
これの欠点は、すべての結果を一時テーブルに挿入する必要があることですが、少なくともそれはキーだけです。これはMSSQLで機能しますが、最小限の調整ですべてのDBで機能するはずです。
@page_number int、@page_sizeintを宣言します-ここに追加の検索パラメーターを追加します
--ID列とIDを使用して一時テーブルを作成します--
選択するレコードの。これはメモリ内のテーブルであるため、
挿入する行数が
10,000を超える場合は、代わりにtempdbの一時テーブルを使用する必要があります
。これを行うには、
-CREATE TABLE #temp_table(row_num int IDENTITY(1,1)、objectid int)
-を使用し、@temp_tableへのすべての参照を#temp_tableに変更します。DECLARE@
temp_table TABLE(row_num int IDENTITY(1,1) 、objectid int)--レコードのIDを使用して一時テーブルに挿入します
--戻ります。-による順序が返されるレコードの順序を反映していることを確認することが重要です。
これにより、row_num
--valuesが正しい順序で設定され
、ページ
INSERT INTO @temp_table(objectid )。/ *例:レコードを一時テーブルに挿入する選択
SELECT personid
FROM person WITH(NOLOCK)
内部結合度WITH(NOLOCK)ondegree.personid = person.personid
WHERE person.lastname = @last_name
ORDER BY person.lastname asc、person .firsname asc
* /--一致した行の総数を取得します
DECLARE@total_rowsint
SET @total_rows =@@ROWCOUNT--一致した行の数 とパラメータとして渡されたページサイズに
基づいてページの総数を計算しますDECLARE @total_pagesint- 行の総数に@page_size-1を追加して、 ページの総数を計算します。これは、sql -- alwasyが整数の除算に切り捨てられるためですSET@total_pages =(@total_rows + @page_size --1)/ @page_size
--@temp_tableに結合し、row_numでフィルタリングして目的の結果セットを
返します/ *例:返すデータを選択します。挿入が適切に行われた場合は 、@temp_tableのobjectid列に戻る行を
含むテーブルを常に結合する必要があります。SELECTperson 。*
FROMperson WITH(NOLOCK)INNER JOIN @temp_table tt
ON person.personid = tt.objectid
* /
-関心のあるページの行のみを
返し、@のrow_num列で並べ替えますtemp_tableを確認してください-
正しいレコードを選択しています
WHEREtt.row_num<(@page_size * @page_number)+ 1
AND tt.row_num>(@page_size * @page_number)-@page_size
ORDER BY tt.row_num
MS Sqlでもこの問題に直面しています...制限または行番号関数はありません。私がしていることは、最終的なクエリ結果 (または場合によってはフィールドのリスト全体) のキーを ID 列を持つ一時テーブルに挿入することです...次に、一時テーブルから必要な範囲外のものをすべて削除します...次に使用しますキーと元のテーブルを結合して、必要なアイテムを取り戻します。これは、適切な一意のキーがあれば機能しますが、そうでない場合は... それ自体が設計上の問題です。
パフォーマンスがわずかに向上する代替手段は、削除手順をスキップして、最終的な結合で行番号のみを使用することです。もう 1 つのパフォーマンスの向上は、TOP 演算子を使用することです。これにより、少なくとも、目的の末尾を過ぎたものを取得する必要がなくなります。
だから...疑似コードで...アイテム80-89を取得するには...
create table #keys (rownum int identity(1,1), key varchar(10))
insert #keys (key)
select TOP 89 key from myTable ORDER BY whatever
delete #keys where rownumber < 80
select <columns> from #keys join myTable on #keys.key = myTable.key
コードでページングを行うことになりました。ループの最初のレコードをスキップするだけです。
ページングを行うための簡単な方法を作成したと思っていましたが、パーベイシブ SQL ではサブクエリで順序句を使用できないようです。しかし、これは他の DB でも動作するはずです (firebird でテストしました)。
select *
from (select top [rows] * from
(select top [rows * pagenumber] * from mytable order by id)
order by id desc)
order by id