常用数据库(MsSql,Oralce,MySql)用SQL实现分页查询

    技术2022-05-20  31

    一、SQL Server         从数据库表中的第M条记录开始取N条记录,利用Top关键字:注意如果Select语句中既有top,又有order by,则是从排序好的结果集中选择:         语句形式: SELECT TOP 10 * FROM TestTable WHERE (ID >           (SELECT MAX(id)          FROM (SELECT TOP 20 id                  FROM TestTable                  ORDER BY id) AS T)) ORDER BY ID

    SELECT TOP 页大小 * FROM TestTable WHERE (ID >           (SELECT MAX(id)          FROM (SELECT TOP 页大小*页数 id                  FROM 表                  ORDER BY id) AS T)) ORDER BY ID     二、SQL Server 2005

    Sql Server 2005中,我可以利用新增函数row_number()来更高效的实现

    select * from (   select row_number() over (order by StudentInfoId) row,* from StudentInfo ) StudentInfo   where row between @PageSize*(@PageIndex-1) and @PageSize*@PageIndex

    或者

          SELECT TOP 10 *       FROM       (        SELECT top 10 [InstanceName], [UserName], [ReportID],        [TimeStart], [TimeEnd],ROW_NUMBER() OVER (ORDER BY ReportID) AS RowNo        FROM [ExecutionLog]       ) AS A       WHERE RowNo > " + pageIndex*10     pageIndex就是我们需要数据的页数,10是每页显示的记录数。

    三、Oralce数据库

    一种通用的分页SQL格式为(该方法也是Hibernate中针对Oracle采用的方式):

    SELECT * FROM  

    (  

    SELECT A.*, ROWNUM RN  

    FROM (SELECT * FROM TABLE_NAME) A  

    WHERE ROWNUM <= 40  

    )  

    WHERE RN >= 21 

     

    其中最内层的查询SELECT * FROM TABLE_NAME表示不进行翻页的原始查询语句。ROWNUM <= 40和RN >= 21控制分页查询的每页的范围。

    上面给出的这个Oracle分页查询语句,在大多数情况拥有较高的效率。分页的目的就是控制输出结果集大小,将结果尽快的返回。在上面的分页查询语句中,这种考虑主要体现在WHERE ROWNUM <= 40这句上。

    选择第21到40条记录存在两种方法,一种是上面例子中展示的在查询的第二层通过ROWNUM <= 40来控制最大值,在查询的最外层控制最小值。而另一种方式是去掉查询第二层的WHERE ROWNUM <= 40语句,在查询的最外层控制分页的最小值和最大值。这是,查询语句如下:

    SELECT * FROM  

    (  

    SELECT A.*, ROWNUM RN  

    FROM (SELECT * FROM TABLE_NAME) A  

    )  

    WHERE RN BETWEEN 21 AND 40 

     

    对比这两种写法,绝大多数的情况下,第一个查询的效率比第二个高得多。

    这是由于CBO优化模式下,Oracle可以将外层的查询条件推到内层查询中,以提高内层查询的执行效率。对于第一个查询语句,第二层的查询条件 WHERE ROWNUM <= 40就可以被Oracle推入到内层查询中,这样Oracle查询的结果一旦超过了ROWNUM限制条件,就终止查询将结果返回了。

    而第二个查询语句,由于查询条件BETWEEN 21 AND 40是存在于查询的第三层,而Oracle无法将第三层的查询条件推到最内层(即使推到最内层也没有意义,因为最内层查询不知道RN代表什么)。】因此,对于第二个查询语句,Oracle最内层返回给中间层的是所有满足条件的数据,而中间层返回给最外层的也是所有数据。数据的过滤在最外层完成,显然这个效率要比第一个查询低得多。

    上面分析的查询不仅仅是针对单表的简单查询,对于最内层查询是复杂的多表联合查询或最内层查询包含排序的情况一样有效。

    关于Oracle的ROWNUM的一点说明:

    在Oracle中,ROWNUM不应该直接应用于>,>=,=,between...and,只能用以符号(<、<=、!=),并非说用>, >=,=,between..and 时会提示SQL语法错误,而是经常是查不出一条记录来。但如果就是想要用 ROWNUM > 10 这种条件的话话就要用嵌套语句,把 ROWNUM 先生成并给其命名别名,然后对他进行查询。

    select *

    from (selet rownum as rn,t1.* from a where ...)

    where rn >10

    四、My sql数据库         My sql数据库最简单,是利用mysql的LIMIT函数,LIMIT [offset,] rows从数据库表中M条记录开            始检索N条记录的语句为:         SELECT * FROM 表名称 LIMIT M,N

             例如从表Sys_option(主键为sys_id)中从10条记录还是检索20条记录,语句如下:          select * from sys_option limit 10,20


    最新回复(0)