MSSql Server基础学习系列———分页查询

来源:互联网 发布:汉仪字体下载包 mac 编辑:程序博客网 时间:2024/05/16 15:08

一、引入

        通过前面的查询学习,我们知道,查询有DataReader和DataSet两种方式。不同的是,前者查询出来的结果集是放在数据库服务器上的,我们每次只能只进一条一条的读取数据,而且在读取的过程中,数据库必须是打开的。后者是把数据库服务器上的结果集保存到本地应用程序内存中,注意,此时是把从数据库服务器上查询到的结果集都放到本地内存中了。如果数据量不大,无所谓,可要是很大的话就会很占用本地内存,甚至造成本地内存的溢出。(C/S架构的项目中,本地的内存一般都是够用的;B/S架构的项目中,用户的并发访问量很大,如果针对每个用户的查询请求都把结果集放到本地,这对应用程序服务器内存该是多么可怕的一件事情啊。)个人认为,对应C/S架构的项目,两种读取方式都可以,对于B/S架构的项目,最好使用前者。

         前面讲的是数据库数据的完全查询,现实中,客户还需要进行部分查询。如,我只需要第三页的数据,其他的我都不需要,这个时候就牵扯到数据的分页查询了。

二、基础知识

        分页有高效和低效两种
高效:先在数据库中对数据分页,之后根据sql语句进行对应页数数据集的查询

低效:把结果集都查询出来放到本地,再对本地中的结果集进行分页、查询

        第一种方法就不用我多说了,可以减轻服务器压力、降低网络负载、节省内存等。第二种方法就是一种出力不讨好的做法,具体不再累述,相信大家也都能理解。

三、分页方法

        现在主要针对第一种分页进行高效分页方法的学习

分页有两种做法:

(1)子查询

可以在所有版本的数据库,通过子查询来做 查询出n-1页的数据作为子查询结果

  select top 10 * from dbo.Publish  where PNO not in   (  select PNO from dbo.Publish  where PNO between 11 and 20  )


--公式化 设要查询第n页,页大小为pselect top p * from 表名where 主键 not in (select top (n-1)*p 主键 from表名)
简单点理解就是你需要21~30之间的10条数据,那我就查询出前30条数据,再把之前1~19之间的数据排除掉,就可以得到21~30之间的10条数据

(2)函数 Row_Number()
在2005(含)以后的版本中存在

--为我们的每一行产生一个编号  疑问点:为何要指定主键意外的列进行排序

select * from dbo.Publish

大家通过上面图片的红色标注应该看出来了,我们把所有的数据都查询出来时也能在左侧产生一个编号,可问题是这个编号我们能用吗?

  select * from(  select *,ROW_NUMBER() over(order by PName) as [序号]  from dbo.Publish  ) as t  where 序号 between 1 and 10

上面就是通过执行Row_Number()得到的结果,我们可以看到在右侧增加了一列:序号 他是从1开始排序的,无论之前的数据是怎么样,当我们在上面的sql语句中通过over语句定义过排序规则并确定好列名之后,新产生的列的编号都是从1开始的。

--公式化 查询第n页,每页大小为p

select * from(select * ,ROW_NUMBER() over(order by  排序字段) as 别名 from 表名)as twhere 别名 between (n-1)*p+1 and n*p

注:

(1)上面写的都是select * 查询所有字段,当然也可以查询部分字段

(2)使用Row_Number()函数的时候一定要带上over()

(3)over(order by 字段)中的字段可以选择升序也可以选择降序,还可以选择按多个字段进行排序

0 0
原创粉丝点击