Pervasive SQL 中的分页

Posted

技术标签:

【中文标题】Pervasive SQL 中的分页【英文标题】:Paging in Pervasive SQL 【发布时间】:2008-09-23 19:04:06 【问题描述】:

如何在 Pervasive SQL(9.1 版)中进行分页?我需要做类似的事情:

//mysql
SELECT foo FROM table LIMIT 10, 10

但我找不到定义偏移量的方法。

【问题讨论】:

【参考方案1】:

在 PSQL 中测试的查询:

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

对于所有 n = no.of 记录,您需要一次获取。 并且 k = n 的倍数(例如 n=5;k=0,5,10,15,....)

【讨论】:

【参考方案2】:

我们的分页要求我们能够将当前页码和页面大小(以及一些额外的过滤器参数)作为变量传递。由于 select top @page_size 在 MS SQL 中不起作用,我们想出一个临时表或变量表来为每行主键分配一个标识,以后可以根据所需的页码和大小对其进行过滤。

** 请注意,如果您有 GUID 主键或复合键,则只需将临时表上的对象 id 更改为唯一标识符或将其他键列添加到表中。

这样做的缺点是它仍然必须将所有结果插入到临时表中,但至少它只是键。这在 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 声明 @temp_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) 在 degree.personid = person.personid WHERE person.lastname = @last_name ORDER BY person.lastname asc, 人名 asc */

--获取我们匹配的总行数 DECLARE @total_rows 整数 SET @total_rows = @@ROWCOUNT --根据页数计算总页数 -- 匹配的行数和作为参数传入的页面大小 DECLARE @total_pages 整数 --将@page_size - 1 添加到的总行数 --计算总页数。这是因为 sql --alwasy 对整数除法进行四舍五入 SET @total_pages = (@total_rows + @page_size - 1) / @page_size

--通过加入返回我们感兴趣的结果集 --返回@temp_table 并按row_num 过滤/* 示例: 选择要返回的数据。如果 插入已正确完成,然后 你应该总是加入表 包含要返回的行 到 objectid 列 @temp_table

选择人。* FROM 人 (NOLOCK) 内部联接 @temp_table tt ON person.personid = tt.objectid */ --仅返回页面中我们感兴趣的行 --并按@temp_table 的row_num 列排序以确保 --我们正在选择正确的记录 WHERE tt.row_num AND tt.row_num > (@page_size * @page_number) - @page_size 订单 BY tt.row_num

【讨论】:

【参考方案3】:

我在 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

【讨论】:

【参考方案4】:

我最终在代码中进行了分页。我只是跳过循环中的第一条记录。

我以为我为进行分页创造了一种简单的方法,但似乎普遍的 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

【讨论】:

以上是关于Pervasive SQL 中的分页的主要内容,如果未能解决你的问题,请参考以下文章

UIScrollview 分页中的 UITextview

摆脱报告中的分页符

如何避免报表中的分页:创建没有分页符的报表?

Angular 5中的分页索引号

在使用 graphql 缓存的基于游标的分页中跟踪页码

PL/SQL 中的分页符