質問

Pervasive SQL (バージョン 9.1) でページングを行うにはどうすればよいですか?次のようなことを行う必要があります。

//MySQL
SELECT foo FROM table LIMIT 10, 10

しかし、オフセットを定義する方法が見つかりません。

役に立ちましたか?

解決 4

結局、コードでページングを行うことになりました。ループ内の最初のレコードをスキップするだけです。

ページングを行う簡単な方法を思いついたと思ったのですが、どうやら Pervasive SQL ではサブクエリでの order 句が許可されていないようです。しかし、これは他のDBでも動作するはずです(私はFirebirdでテストしました)

select *
from (select top [rows] * from
(select top [rows * pagenumber] * from mytable order by id)
order by id desc)
order by id

他のヒント

PSQL でテストされたクエリ:

select top n * 
from tablename 
where id not in(
select top k id
from tablename 
) 

すべての n = 一度にフェッチする必要があるレコードの数。k = n の倍数(例:n=5;k=0,5,10,15,....)

ページングでは、現在のページ番号とページ サイズ (いくつかの追加のフィルター パラメーターとともに) を変数として渡すことができる必要がありました。MS SQL では select top @page_size が機能しないため、一時テーブルまたは変数テーブルを作成して、各行の主キーに ID を割り当て、後で必要なページ番号とサイズでフィルタリングできるようにすることを考え出しました。

** GUID 主キーまたは複合キーがある場合は、一時テーブルのオブジェクト ID を uniqueidentifier に変更するか、追加のキー列をテーブルに追加するだけでよいことに注意してください。

この欠点は、すべての結果を一時テーブルに挿入する必要があることですが、少なくともキーのみを挿入する必要があることです。これは MS SQL で機能しますが、最小限の調整でどの DB でも機能するはずです。

@page_number int、@page_size intを宣言 - ここに追加の検索パラメーターを追加する

-- ID 列と ID を含む一時テーブルを作成します。
--選択するレコードの。これは記憶にあるものです
--table、挿入する行数が多い場合
-- 10,000 を超える場合は、tempdb の一時テーブルを使用する必要があります。
- その代わり。これを行うには、次を使用します
--CREATE TABLE #temp_table (row_num int IDENTITY(1,1), objectid int)
-- そして、@temp_table へのすべての参照を #temp_table に変更します。
@temp_table Tableを宣言する(row_num int dect(1,1)、objectid int)

-- レコードの ID を使用して一時テーブルに挿入します。
--私たちは戻りたいです。までに注文を確実にすることが重要です
--row_num が返されるようにレコードの順序を反映します。
-- 値は正しい順序で設定されており、
-- ページに基づいてレコードを修正します
@temp_table(objectid)に挿入

/* 例:レコードを一時テーブルに挿入することを選択します
個人IDの選択
(nolock)の人から
degree.personid = person.personidで(nolock)との内部結合学位
ここで、person.lastname = @last_name
Person.lastname asc、person.firsname ascによる注文
*/

-- 一致した行の合計数を取得します
@total_rows intを宣言します
@total_rows = @@ rowcountを設定します
-- の数に基づいて合計ページ数を計算します。
-- 一致した行とパラメータとして渡されたページ サイズ
@total_pages intを宣言します
--@page_size - 1 を合計行数に追加します。
-- 総ページ数を計算します。これはSQLだからです
-- 整数の除算では常に切り捨てます
@total_pages =(@total_rows + @page_size -1) / @page_size

-- 結合することで、関心のある結果セットを返します。
-- @temp_table に戻り、row_num でフィルタリングします。
/* 例:返すデータを選択します。挿入が完了した場合
適切に、あなたは常に含まれるテーブルに参加する必要があります
@temp_tableのObjectID列に戻る行

人を選択してください。*
(nolock)内側の参加者から@temp_table tt
on person.personId = tt.objectid
*/
-- ページ内の関心のある行のみを返します
--そして @temp_table の row_num 列で順序付けして確認します。
-- 正しいレコードを選択しています
ここで、tt.row_num <(@page_size * @page_number) + 1
and tt.row_num>(@page_size * @page_number) - @page_size
TT.ROW_NUMによる注文

MS SQLでもこの問題に直面しています...Limit 関数や rownumber 関数はありません。私が行うのは、最終的なクエリ結果のキー (場合によってはフィールドのリスト全体) を 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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top