簡體   English   中英

在普及SQL中分頁

[英]Paging in Pervasive SQL

如何在普及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 =記錄數,您需要一次獲取。 和k = n的倍數(例如n = 5; k = 0,5,10,15,....)

我們的頁面調度要求我們能夠傳遞當前頁碼和頁面大小(以及一些其他過濾器參數)作為變量。 由於select top @page_size在MS SQL中不起作用,因此我們想出了一個臨時表或變量表,為每行主鍵分配一個標識,該標識以后可以根據所需的頁碼和大小進行過濾。

**請注意,如果您具有GUID主鍵或復合鍵,則只需將臨時表上的對象ID更改為uniqueidentifier或向表中添加其他鍵列。

不利的一面是,它仍然必須將所有結果插入臨時表中,但至少它只是鍵。 這在MS SQL中有效,但應該能夠以最小的調整就可以用於任何數據庫。

聲明@page_number int,@page_size int-在此處添加任何其他搜索參數

-使用標識列和ID創建臨時表
-您將選擇的記錄。 這是一個內存中
--table,因此如果您要插入的行數更大
-大於10,000,則應在tempdb中使用臨時表
- 代替。 為此,請使用
--CREATE TABLE #temp_table(row_num int IDENTITY(1,1),objectid int)
-並將所有對@temp_table的引用更改為#temp_table
DECLARE @temp_table表(row_num int IDENTITY(1,1),objectid int)

-插入具有記錄ID的臨時表
-我們要回來。 確保訂單的通過是至關重要的
-反映記錄返回的順序,以便row_num
-值的設置順序正確,我們正在選擇
-根據頁面正確記錄
插入@temp_table(objectid)

/ *示例:選擇將記錄插入到臨時表中
SELECT人員
來自有(NOLOCK)的人
內連接度WITH(NOLOCK)on degree.personid = person.personid
在哪里person.lastname = @last_name
按person.lastname asc,person.firsname asc排序
* /

-獲取我們匹配的總行數
宣告@total_rows int
SET @total_rows = @@ ROWCOUNT
-根據頁數計算總頁數
-匹配的行,並將頁面大小作為參數傳遞
DECLARE @total_pages int
-將@page_size-1添加到要添加的總行數
-計算總頁數。 這是因為sql
--alwasy四舍五入為整數除法
SET @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中遇到此問題...沒有限制或行號功能。 我要做的是將最終查詢結果的鍵(有時甚至是整個字段列表)插入具有標識列的臨時表中……然后我從臨時表中刪除所需范圍之外的所有內容……然后使用連接鍵和原始表,以帶回我想要的項目。 如果您有一個不錯的唯一鍵,這將起作用-如果您沒有,那么...這本身就是設計問題。

性能稍好一點的替代方法是跳過刪除步驟,而僅在最終聯接中使用行號。 另一個性能改進是使用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不允許子查詢中使用order子句。 但這應該適用於其他數據庫(我在firebird上進行了測試)

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM