简体   繁体   English

在普及SQL中分页

[英]Paging in Pervasive SQL

How to do paging in Pervasive SQL (version 9.1)? 如何在普及SQL(版本9.1)中进行分页? I need to do something similar like: 我需要做类似的事情:

//MySQL
SELECT foo FROM table LIMIT 10, 10

But I can't find a way to define offset. 但是我找不到定义偏移量的方法。

Tested query in PSQL: 在PSQL中测试过的查询:

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

for all n = no.of records u need to fetch at a time. 对于所有n =记录数,您需要一次获取。 and k = multiples of n(eg. n=5; k=0,5,10,15,....) 和k = n的倍数(例如n = 5; k = 0,5,10,15,....)

Our paging required that we be able to pass in the current page number and page size (along with some additional filter parameters) as variables. 我们的页面调度要求我们能够传递当前页码和页面大小(以及一些其他过滤器参数)作为变量。 Since a select top @page_size doesn't work in MS SQL, we came up with creating an temporary or variable table to assign each rows primary key an identity that can later be filtered on for the desired page number and size. 由于select top @page_size在MS SQL中不起作用,因此我们想出了一个临时表或变量表,为每行主键分配一个标识,该标识以后可以根据所需的页码和大小进行过滤。

** Note that if you have a GUID primary key or a compound key, you just have to change the object id on the temporary table to a uniqueidentifier or add the additional key columns to the table. **请注意,如果您具有GUID主键或复合键,则只需将临时表上的对象ID更改为uniqueidentifier或向表中添加其他键列。

The down side to this is that it still has to insert all of the results into the temporary table, but at least it is only the keys. 不利的一面是,它仍然必须将所有结果插入临时表中,但至少它只是键。 This works in MS SQL, but should be able to work for any DB with minimal tweaks. 这在MS SQL中有效,但应该能够以最小的调整就可以用于任何数据库。

declare @page_number int, @page_size int -- add any additional search parameters here 声明@page_number int,@page_size int-在此处添加任何其他搜索参数

--create the temporary table with the identity column and the id -使用标识列和ID创建临时表
--of the record that you'll be selecting. -您将选择的记录。 This is an in memory 这是一个内存中
--table, so if the number of rows you'll be inserting is greater --table,因此如果您要插入的行数更大
--than 10,000, then you should use a temporary table in tempdb -大于10,000,则应在tempdb中使用临时表
--instead. - 代替。 To do this, use 为此,请使用
--CREATE TABLE #temp_table (row_num int IDENTITY(1,1), objectid int) --CREATE TABLE #temp_table(row_num int IDENTITY(1,1),objectid int)
--and change all the references to @temp_table to #temp_table -并将所有对@temp_table的引用更改为#temp_table
DECLARE @temp_table TABLE (row_num int IDENTITY(1,1), objectid int) DECLARE @temp_table表(row_num int IDENTITY(1,1),objectid int)

--insert into the temporary table with the ids of the records -插入具有记录ID的临时表
--we want to return. -我们要回来。 It's critical to make sure the order by 确保订单的通过是至关重要的
--reflects the order of the records to return so that the row_num -反映记录返回的顺序,以便row_num
--values are set in the correct order and we are selecting the -值的设置顺序正确,我们正在选择
--correct records based on the page -根据页面正确记录
INSERT INTO @temp_table (objectid) 插入@temp_table(objectid)

/* Example: Select that inserts records into the temporary table / *示例:选择将记录插入到临时表中
SELECT personid SELECT人员
FROM person WITH (NOLOCK) 来自有(NOLOCK)的人
inner join degree WITH (NOLOCK) on degree.personid = person.personid 内连接度WITH(NOLOCK)on degree.personid = person.personid
WHERE person.lastname = @last_name 在哪里person.lastname = @last_name
ORDER BY person.lastname asc, person.firsname asc 按person.lastname asc,person.firsname asc排序
*/ * /

--get the total number of rows that we matched -获取我们匹配的总行数
DECLARE @total_rows int 宣告@total_rows int
SET @total_rows = @@ROWCOUNT SET @total_rows = @@ ROWCOUNT
--calculate the total number of pages based on the number of -根据页数计算总页数
--rows that matched and the page size passed in as a parameter -匹配的行,并将页面大小作为参数传递
DECLARE @total_pages int DECLARE @total_pages int
--add the @page_size - 1 to the total number of rows to -将@page_size-1添加到要添加的总行数
--calculate the total number of pages. -计算总页数。 This is because sql 这是因为sql
--alwasy rounds down for division of integers --alwasy四舍五入为整数除法
SET @total_pages = (@total_rows + @page_size - 1) / @page_size SET @total_pages =(@total_rows + @page_size-1)/ @page_size

--return the result set we are interested in by joining -通过加入返回我们感兴趣的结果集
--back to the @temp_table and filtering by row_num -返回@temp_table并按row_num进行过滤
/* Example: Selecting the data to return. / *示例:选择要返回的数据。 If the insert was done 如果插入完成
properly, then you should always be joining the table that contains 正确,那么您应该始终加入包含以下内容的表
the rows to return to the objectid column on the @temp_table 返回到@temp_table上的objectid列的行

SELECT person.* 选择的人。*
FROM person WITH (NOLOCK) INNER JOIN @temp_table tt 来自拥有(NOLOCK)内部联接@temp_table tt的人
ON person.personid = tt.objectid ON person.personid = tt.objectid
*/ * /
--return only the rows in the page that we are interested in -仅返回我们感兴趣的页面中的行
--and order by the row_num column of the @temp_table to make sure -并按@temp_table的row_num列排序,以确保
--we are selecting the correct records -我们正在选择正确的记录
WHERE tt.row_num < (@page_size * @page_number) + 1 其中tt.row_num <(@page_size * @page_number)+ 1
AND tt.row_num > (@page_size * @page_number) - @page_size AND tt.row_num>(@page_size * @page_number)-@page_size
ORDER BY tt.row_num 按tt.row_num排序

I face this problem in MS Sql too... no Limit or rownumber functions. 我也在MS Sql中遇到此问题...没有限制或行号功能。 What I do is insert the keys for my final query result (or sometimes the entire list of fields) into a temp table with an identity column... then I delete from the temp table everything outside the range I want... then use a join against the keys and the original table, to bring back the items I want. 我要做的是将最终查询结果的键(有时甚至是整个字段列表)插入具有标识列的临时表中……然后我从临时表中删除所需范围之外的所有内容……然后使用连接键和原始表,以带回我想要的项目。 This works if you have a nice unique key - if you don't, well... that's a design problem in itself. 如果您有一个不错的唯一键,这将起作用-如果您没有,那么...这本身就是设计问题。

Alternative with slightly better performance is to skip the deleting step and just use the row numbers in your final join. 性能稍好一点的替代方法是跳过删除步骤,而仅在最终联接中使用行号。 Another performance improvement is to use the TOP operator so that at the very least, you don't have to grab the stuff past the end of what you want. 另一个性能改进是使用TOP运算符,这样至少您不必将所需的东西都拿走。

So... in pseudo-code... to grab items 80-89... 所以...用伪代码...抓取物品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

I ended up doing the paging in code. 我最终在代码中进行了分页。 I just skip the first records in loop. 我只是跳过循环中的第一条记录。

I thought I made up an easy way for doing the paging, but it seems that pervasive sql doesn't allow order clauses in subqueries. 我以为我做了一种简单的分页方法,但是似乎普及的sql不允许子查询中使用order子句。 But this should work on other DBs (I tested it on firebird) 但这应该适用于其他数据库(我在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