取指定分页内容,一般思路是跳过多少行然后取接下来的几行

这里有两个参数 PageIndex,PageSize,(假定PageIndex是从0开始)

使用Linq的语法是  

var  list = Items.Skip(PageIndex * PageSize).Task(PageSize).ToList();

但是Sql Server没有跳过这个概念,只有一个Top,那么要如何分页?

使用top进行分页

select * 
from (
    select top pageSize * 
    from (
        select top (pageIndex*pageSize) * 
        from student 
        order by sNo asc 
    ) as temp_sum_student  -- 其中里面这层,必须指定按照升序排序,省略的话,查询出的结果是错误的。

    order by sNo desc ) temp_order
order by sNo asc

思路:

使用top语法,将包含页的数据都取出来,例如要取第2页的数据(这里每页10行,下同),那么将第1页,和第2页的数据都取出来

这个时候我们要的第2页数据就在取出来的最后面

我们再来个反序,将它放到最前面,再取top出来

这个时候因为反序了一下,那么再来个反序,最终数据就有了

缺点:

前面几页数据的性能还可以,越往后越慢,例如你要找100页后的数据,你就要将100页的数据都读出来


使用主键进行分页


-- 分页查询(通用型)
select top pageSize * 
from student 
where sNo>=
(select max(sNo) 
from (select top ((pageIndex-1)*pageSize+1) sNo
from student 
order by  sNo asc) temp_max_ids) 
order by sNo;

思路:

假定有100行数据,要取第二页数据,即11-20行,

假定主键就是从1到100,那么要取的就是 大于10后,取10条

缺点:

只能按主键排序


利用not in 关键字


-- 分页查询(通用型)
select top pageSize * 
from student where id not in (select top  rownumber*pageSize id 
from student) 

思路:

跟使用top进行分页类似(not in 的性能应该更差,具体没试过)


row_number() over(order by id)关键字

-- 分页查询(通用型)
select top pageSize * 
from (select row_number() 
over(order by sno asc) as rownumber,* 
from student) temp_row
where rownumber>((pageIndex-1)*pageSize);

思路:

跟使用主键分页类似,这里使用窗口函数得到每一行的行号,因为行号是连续的,这里只需要确认从大于第几行开始取,取多少即可


offset /fetch next(2012版本及以上才有)

-- 分页查询(通用型)
select * from student
order by sno 
offset ((@pageIndex-1)*@pageSize) rows
fetch next @pageSize rows only;

这个跟最最开始说的思路就类似了,offset是偏移的意思,也就是跳过多少行,fetch next 是取接下来的几行