sqlServer如何实现分页查询

你的名字 2024-03-31 10:10 246阅读 0赞

sqlServer的分页查询和mysql语句不一样,有三种实现方式。分别是:offset /fetch next、利用max(主键)、利用row_number关键字

一、offset /fetch next关键字

2012版本及以上才有,SQL server公司升级后推出的新方法。
公式:

  1. -- 分页查询公式-offset /fetch next
  2. select * from 表名
  3. order by 主键 其他索引列
  4. -- @pageIndex:页码、@pageSize:每页记录数
  5. offset ((@pageIndex-1)*@pageSize) rows
  6. fetch next @pageSize rows only;

示例:

  1. -- 分页查询第2页,每页有10条记录
  2. select * from tb_user
  3. order by uid
  4. offset 10 rows
  5. fetch next 10 rows only ;

说明:
offset 10 rows ,将前10条记录舍去,fetch next 10 rows only ,向后再读取10条数据。

二、利用max(主键)

公式:

  1. -- 分页查询公式-利用max(主键)
  2. select top @pageSize *
  3. from 表名
  4. where 主键>=
  5. (select max(主键)
  6. from (
  7. select top ((@pageIndex-1)*@pageSize+1) 主键
  8. from 表名
  9. order by 主键 asc) temp_max_ids)
  10. order by 主键;

示例:

  1. -- 分页查询第2页,每页有10条记录
  2. select top 10 *
  3. from tb_user
  4. -- 3、再重新在这个表查询前10条,条件: id>=max(id)
  5. where uid>=
  6. -- 2、利用maxid)得到前11条记录中最大的id
  7. (select max(uid)
  8. from (
  9. -- 1、先top11条行记录
  10. select top 11 uid
  11. from tb_user
  12. order by uid asc) temp_max_ids)
  13. order by uid;

说明:
先top前11条行记录,然后利用max(id)得到最大的id,之后再重新在这个表查询前10条,不过要加上条件,where id>=max(id)。

中心思想:其实就是先得到该页的初始id,PS:别忘了加上排序哦

三、利用row_number关键字

这种方式也是比较常用的,直接利用row_number() over(order by id)函数计算出行数,选定相应行数返回即可,不过该关键字只有在SQL server 2005版本以上才有。
公式:

  1. -- 分页查询公式-row_number()
  2. select top @pageSize *
  3. from (
  4. -- rownumber是别名,可按自己习惯取
  5. select row_number() over(order by 主键 asc) as rownumber,*
  6. from 表名) temp_row
  7. where rownumber>((@pageIndex-1)*@pageSize);

示例:

  1. -- 分页查询第2页,每页有10条记录
  2. select top 10 *
  3. from (
  4. -- 子查询,多加一个rownumber列返回
  5. select row_number() over(order by uid asc) as rownumber,*
  6. from tb_user) temp_row
  7. --限制起始行标
  8. where rownumber>10;

说明:
利用row_number函数给每行记录标了一个序号,相当于在原表中多加了1列返回。
上述示例,是以序号11为起始行,查询前10条记录,即为第2页数据。
在这里插入图片描述

优化:
可以看到,子查询查询了全表数据,如果数据量大,效率是比较低的。
下面是优化后的SQL,
公式:

  1. -- 分页查询公式-row_number()-优化版本
  2. select *
  3. from (
  4. -- rownumber是别名,可按自己习惯取
  5. select top (@pageIndex*@pageSize) row_number() over(order by 主键 asc)
  6. as rownumber,*
  7. from 表名) temp_row
  8. where rownumber>((@pageIndex-1)*@pageSize);

示例:

  1. -- 分页查询第2页,每页有10条记录
  2. select *
  3. from (
  4. -- 子查询,限制了返回前20条数据
  5. select top 20 row_number() over(order by uid asc) as rownumber,*
  6. from tb_user) temp_row
  7. --限制起始行标
  8. where rownumber>10;

说明:
这里,子查询仅查询到当前页的最后一行,没有进行全表查询,所以效率上要快一点。在外层限制起始行标,是没变的,但是却在内层控制了结尾行标。
上述示例,是以序号11为起始行,查询20以内的记录,即为第2页数据。

mybatis用法示例:

  1. @Select("<script>SELECT "+columnAll+" FROM( SELECT TOP (${param.page * param.pageSize}) ROW_NUMBER() OVER (ORDER BY update_time desc,stock_type desc) AS rownumber,* " +
  2. "FROM product_stock_log WITH(NOLOCK) "
  3. + " <where> "
  4. + "<if test='param.param.sequence!=null'> and sequence=#{param.param.sequence} </if> "
  5. + "<if test='param.param.seachCreateStartTime != null'>"
  6. + " and create_time >= #{param.param.seachCreateStartTime} "
  7. + "</if>"
  8. + "<if test='param.param.seachCreateEndTime != null'>"
  9. + " and create_time <= #{param.param.seachCreateEndTime} "
  10. + "</if>"
  11. + " </where> "
  12. +" ) temp_row WHERE rownumber>((#{param.page}-1)*#{param.pageSize}) "
  13. + "</script>")
  14. List<ProductStockLog> findForPage(@Param("param") PageParam<ProductStockLogQuery> where);

更多介绍,可查看我的另外篇文章:SQL Server中row_number函数用法介绍

发表评论

表情:
评论列表 (有 0 条评论,246人围观)

还没有评论,来说两句吧...

相关阅读