作者:黎波

一、相关概念

     在 ACCESS 数据库中,一个表的主键(PRIMARY KEY,又称主索引)上必然建立了唯一索引(UNIQUE INDEX),因此主键字段的值是不会重复的。并且索引页依据索引列的值进行排序,每个索引记录包含一个指向它所引用的数据行的指针。我们可以利用主键这两个特点来实现对某条记录的定位,从而快速地取出某个分页上要显示的记录。
 
     举个例子,假设主键字段为 INTEGER 型,数据库表中的记录已经按主键字段的值升序排好,那么主键字段的值为“11”的记录肯定刚好在值为“12”的记录前面(假设数据库表中存在主键的值为“12”的记录)。如果主键字段不具备 UNIQUE 约束,数据库表中将有可能存在两个或两个以上主键字段的值为“11”的记录,这样就无法确定这些记录之间的前后位置了。
 
     下面就让我们看看如何利用主键来进行数据的分段查询吧。

二、升序

(1)@PageIndex <= @FirstIndex
 
     取第一页的数据是再简单不过了,我们只要用TOP @PageSize 就可以取出第一页要显示的记录。因为数据表中的记录已经按主键字段的值升序排好,所以省去了 ORDER BY 子句,速度更快。
SELECT TOP @PageSize @QueryFields
FROM @TableName
WHERE @Condition
-- ORDER BY @PrimaryKey ASC
 
如图:@PageIndex = 0
(2)@FirstIndex < @PageIndex <= @MiddleIndex
     把取数据表前半部分记录和取后半部分记录的 SQL 语句分开写,可以有效地改善性能。后面我再详细解释这个问题。现在看看取前半部分记录的 SQL 语句。先取出当前页之前的所有记录的主键值,再从中选出最大值,然后取出主键值大于该最大值的前 @PageSize 条记录。值得注意的是,这里省去了两个 ORDER BY @PrimaryKey ASC 语句,分别在最里面和最外面的 SELECT 语句。前面已经说过,数据库表中的记录已经按主键字段的值升序排好,所以我们没有必要画蛇添足。
SELECT TOP @PageSize @QueryFields
FROM @TableName
WHERE @PrimaryKey > (
     SELECT MAX(@PrimaryKey) FROM (
          SELECT TOP @PageSize*@PageIndex @PrimaryKey
          FROM @TableName
          WHERE @Condition
          -- ORDER BY @PrimaryKey ASC
      ) TableA
) WHERE @Condition
-- ORDER BY @PrimaryKey ASC
例如:@PageIndex = 1 ,红 --> 黄 --> 蓝
 
(3)@MiddleIndex < @PageIndex < @LastIndex
     接下来看看取数据表后半部分记录的 SQL 语句。该语句跟前面的语句算法的原理是一样的,只是方法稍微不同。
 
     先取出当前页之后的所有记录的主键值,再从中选出最小值,然后取出主键值小于该最小值的前 @PageSize 条记录。
SELECT * FROM (
     SELECT TOP @PageSize @QueryFields
     FROM @TableName
     WHERE @PrimaryKey < (
          SELECT MIN(@PrimaryKey) FROM (
               SELECT TOP (@RecordCount-@PageSize*(@PageIndex+1)) @PrimaryKey
               FROM @TableName
               WHERE @Condition
               ORDER BY @PrimaryKey DESC
          ) TableA
     ) WHERE @Condition
     ORDER BY @PrimaryKey DESC
) TableB
ORDER BY @PrimaryKey ASC
 
     之所以把取数据表前半部分记录和取后半部分记录的 SQL 语句分开写,是因为使用取前半部分记录的 SQL 语句时,当前页前面的记录数目随页数递增,而我们还要从这些记录中取出它们的主键字段的值再从中选出最大值。这样一来,分页速度将随着页数的增加而减慢。因此我没有这样做,而是在当前页索引大于中间页索引时(@MiddleIndex < @PageIndex)选用了分页速度随着页数的增加而加快的算法。由此可见,假设把所有分页面划分为前面、中间和后面三部分,则最前面和最后面的分页速度最快,最中间的分页速度最慢。
例如:@PageIndex = 3 ,红 --> 黄 --> 蓝
 
 
(4)@PageIndex >= @LastIndex
 
     取最后一页的记录时要先计算出该页的记录数,作为 TOP 语句的条件,而不能直接用 TOP @PageSize,这样取出来的记录并不只是最后一页的。其实很多网站确实这样做。
 
SELECT * FROM (
     SELECT TOP (@RecordCount-@PageSize*@LastIndex) @QueryFields
     FROM @TableName
     WHERE @Condition
     ORDER BY @PrimaryKey DESC
) TableA
ORDER BY @PrimaryKey ASC
 
例如:@PageIndex = 4

三、降序

(1)@PageIndex <= @FirstIndex
SELECT TOP @PageSize @QueryFields
FROM @TableName
WHERE @Condition
ORDER BY @PrimaryKey DESC
 
(2)@FirstIndex < @PageIndex <= @MiddleIndex
 
SELECT TOP @PageSize @QueryFields
FROM @TableName
WHERE @PrimaryKey < (
    SELECT MIN(@PrimaryKey) FROM (
        SELECT TOP @PageSize*@PageIndex @PrimaryKey
        FROM @TableName
        WHERE @Condition
        ORDER BY @PrimaryKey DESC
    ) TableA
) WHERE @Condition
ORDER BY @PrimaryKey DESC
 
 
(3)@MiddleIndex < @PageIndex < @LastIndex
SELECT * FROM (
    SELECT TOP @PageSize @QueryFields
    FROM @TableName
    WHERE @PrimaryKey > (
        SELECT MAX(@PrimaryKey) FROM (
            SELECT TOP (@RecordCount-@PageSize*(@PageIndex+1)) @PrimaryKey
            FROM @TableName
            WHERE @Condition
            -- ORDER BY @PrimaryKey ASC
        ) TableA
    ) WHERE @Condition
    -- ORDER BY @PrimaryKey ASC
) TableB
ORDER BY @PrimaryKey DESC
 
 
(4)@PageIndex >= @LastIndex
 
SELECT * FROM (
    SELECT TOP (@RecordCount-@PageSize*@LastIndex) @QueryFields
    FROM @TableName
    WHERE @Condition
    ORDER BY @PrimaryKey ASC
) TableA
ORDER BY @PrimaryKey DESC

四、总结

       通过上面的讨论,相信大家应该看到了该分页方法的优势所在。在下一篇中,我将给大家一个动态生成上面 SQL 语句的类。

DataGrid连接Access的快速分页法(2)——SQL语句的选用(升序与降序)相关推荐

  1. DataGrid连接Access的快速分页法(1)——需求与现状

    作者:黎波 一.需求分析      DataGrid是一个功能强大的ASP.NET Web服务器端控件,它除了能够按各种方式格式化显示数据,还可以对数据进行动态的排序.编辑和分页.大大减轻了广大Web ...

  2. DataGrid连接Access的快速分页法——动态生成SQL语句

    作者:黎波 using System; using System.Text; namespace Paging { /// <summary> /// FastPaging 的摘要说明. ...

  3. DataGrid基于Access的快速分页法

    DataGrid基于Access的快速分页法 撰文/ 黎波 DataGrid是一个功能非常强大的ASP.NET Web服务器端控件,它除了能够方便地按各种方式格式化显示表格中的数据,还可以对表格中的数 ...

  4. java 生成分页sql_DataGrid连接Access的快速分页法——动态生成SQL语句

    作者:黎波usingSystem;usingSystem.Text;namespacePagi 作者:黎波 using System; using System.Text; namespace Pag ...

  5. MySql实现分页查询的SQL,mysql实现分页查询的sql语句 (转)

    摘要:MySQL数据库实现分页查询的SQL语句写法! 一:分页需求: 客户端通过传递start(页码),limit(每页显示的条数)两个参数去分页查询数据库表中的数据,那我们知道MySql数据库提供了 ...

  6. Spring Data JDBC自动生成的增删改查CRUD分页、排序SQL语句非常简洁没有多余的SQL

    通过在application.properties文件中设置记录SQL日志 logging.level.org.springframework.jdbc.core.JdbcTemplate=DEBUG ...

  7. mybatis mysql 分页sql语句_MySql实现分页查询的SQL,mysql实现分页查询的sql语句(转)...

    http://blog.csdn.net/sxdtzhaoxinguo/article/details/51481430 摘要:MySQL数据库实现分页查询的SQL语句写法! 一:分页需求: 客户端通 ...

  8. sqlserver分页模糊查询sql语句

    sqlserver分页模糊查询sql语句 <select id = "queryUserCount" resultType="int" >selec ...

  9. access重复数据累计_ACCESS数据库-sql语句查找重复记录、唯一记录和分组统计方法...

    本例测试环境是EXCEL中用VBA连接ACCESS数据库 有如下一张表,要分别查找出所有同名的人.所有同名并且学号也一样的人以及所有同名但不同学号的人. 查询所有同名人员 select * from ...

最新文章

  1. Luogu P4916 魔力环
  2. mysql5.5连接器_MySQL :: MySQL 5.1参考手册 :: 26. 连接器
  3. 表单oninput和onchange事件区别
  4. linux CentOS7最小化安装环境静默安装Oracle11GR2数据库(执行安装_07)
  5. 让你快乐的21种方法
  6. 解压tar.xz文件
  7. 远程调用——hessian使用入门
  8. mysql数据库插入数据错误Error Code: 1118 - Row size too large ( 8126)
  9. Error : Failed to get convolution algorithm. This is probably because cuDNN failed to initialize, so
  10. 新年跨出第一步:人工智能实施这样做!
  11. 华为p4不是鸿蒙吗怎么又改为安卓_鸿蒙系统是不是就是改版的安卓系统?
  12. 拆解老式电饭锅限温器并验证其原理
  13. VSCode常用插件汇总
  14. Neo.4j 使用总结
  15. 黑魂向project制作学习三:摄像头碰撞(Camera Collisions)
  16. 英语--日常生活名词收集 Daily Life Nouns Collection
  17. 3-python 函数篇
  18. 电脑死机故障解决方法全面汇总
  19. IP分片和TCP分段解析--之IP分片
  20. c语言设计模拟闹钟主函数,基于STM32F407的四重感觉人体自然唤醒仪器设计

热门文章

  1. android微博客户端下载,iBeebo微博客户端
  2. c++ char数组初始化_c专题指针数组与指针的关联
  3. 随笔2:关于linux和python
  4. 解决Mask RCNN训练时GPU内存溢出问题
  5. 基于颜色特征,形状特征和纹理特征的数字图像的检索(Digital Image Retrieval)MATLAB GUI实现(本科毕业设计)
  6. PCA(Principal Component Analysis)的原理、算法步骤和实现。
  7. GO Negotiation流程分析
  8. C语言中连续调用rand函数,返回值不变
  9. JAVA导出exls时报oom_如何实现导出百万条数据到EXCEL中不报OOM异常?
  10. Open3d学习计划—高级篇 4(多视角点云配准)