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

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

//MySQL
SELECT foo FROM table LIMIT 10, 10

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

【问题讨论】:

    标签: sql pervasive


    【解决方案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
          

          【讨论】:

            猜你喜欢
            • 2022-10-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-09-29
            • 1970-01-01
            • 1970-01-01
            • 2010-09-09
            • 1970-01-01
            相关资源
            最近更新 更多