如何在 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 = no.of 记录,您需要一次获取。并且 k = n 的倍数(例如 n=5;k=0,5,10,15,....)
我们的分页要求我们能够将当前页码和页面大小(以及一些额外的过滤器参数)作为变量传递。由于 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
DECLARE @temp_table TABLE (row_num int IDENTITY(1,1) , objectid int)--插入带有记录ID的临时表--
我们要返回。确保通过
--reflects 的顺序返回记录的顺序至关重要,以便 row_num
--values 以正确的顺序设置,并且我们
根据页面
INSERT INTO @temp_table (objectid )/* 示例:选择将记录插入临时表
SELECT personid
FROM person WITH (NOLOCK)
inner join degree WITH (NOLOCK) on degree.personid = person.personid
WHERE person.lastname = @last_name
ORDER BY person.lastname asc, person .firstname asc
*/--获取我们匹配的总行数
DECLARE @total_rows int
SET @total_rows = @@ROWCOUNT --根据 匹配的--rows数和作为参数传入的页面大小
计算总页数DECLARE @total_pages int -- 将@page_size - 1 添加到总行数以 -- 计算总页数。这是因为 sql --alwasy 向下舍入以进行整数除法SET @total_pages = (@total_rows + @page_size - 1) / @page_size--return 我们感兴趣的结果集,方法是加入
--back 到 @temp_table 并按 row_num 过滤
/* 示例:选择要返回的数据。如果插入操作
正确,那么您应该始终加入包含
要返回到 @temp_table 上的 objectid 列的行的表SELECT person.*
FROM person WITH (NOLOCK) INNER JOIN @temp_table tt
ON person.personid = tt.objectid
*/
--仅返回页面中我们感兴趣的行
--并按@的row_num列排序temp_table 以确保
-- 我们正在选择正确的记录
WHERE tt.row_num < (@page_size * @page_number) + 1
AND tt.row_num > (@page_size * @page_number) - @page_size
ORDER BY 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