1declare @col int 2 3select top {PageSize * (PageIndex-1)+1} @col = [排序字段] 4from [表名 ¦视图名] 5[ where 查询条件 ] 6order by [排序字段] asc ¦desc 7 8select top PageSize 需要显示的字段 9from [表名 ¦视图名] 10where [排序字段] >= @col 11[ and 查询条件 ] 12order by [排序字段] asc ¦desc 以NorthWind 数据库里的 Products 表为例,假设一页显示10条数据,CategoryID = 3 为查询条件,按照ProductID 倒序,如果想显示第二页的数据,那么SQL语句就是 declare @col int
select top 11 @col = ProductID from Products where CategoryID = 3 order by ProductID desc
select top 10 * from Products where ProductID >= @col and CategoryID = 3 order by ProductID desc 说明: 第一行的定义,要根据字段类型来修改,看是比较麻烦,但是这个麻烦交给分页控件就可以了,使用者,只要设置分页控件的属性就可以了。 第五行和第十一行,如果需要加查询条件的话就可以在这里添加。
第三行是一个“定位”,这个可以算是SQL Server 所特有的吧,也是SQL Server 很宽容的地方。以Products 表的例子,执行完第一条select 语句之后, @col 里面记录的是 在CategoryID = 3 的记录里面,按照ProductID 倒序,排行在11位的记录的值。
[主键字段] asc ¦desc ) as aa order by [排序字段1] desc ¦asc, --如果上面是倒序,那么这里就是正序,下同 [排序字段2] asc ¦desc ,
[主键字段] desc ¦asc
)
order by [排序字段1] asc ¦desc, --如果上面是倒序,那么这里就是正序,所谓颠颠倒倒嘛。 [排序字段2] desc ¦asc,
[主键字段] asc ¦desc 以NorthWind 数据库里的 Products 表为例,假设一页显示10条数据,CategoryID = 3 为查询条件,按照UnitPrice 倒序,由于UnitPrice 字段可能有重复值,所以加上一个排序字段——ProductID ,即按照 UnitPrice desc,ProductID 来排序。 如果想显示第二页的数据,那么SQL语句就是 select * from Products where ProductID in ( select top 10 ProductID from (select top 20 ProductID , UnitPrice from Products where CategoryID = 3 order by UnitPrice desc , ProductID ) as aa order by UnitPrice asc, --如果上面是倒序,那么这里就是正序,下同 ProductID desc ) order by UnitPrice desc, --如果上面是倒序,那么这里就是正序,所谓颠颠倒倒嘛。 ProductID 说明: 1、这里查询条件加一次就可以了。 2、是不是看 asc ¦desc 倒来倒去的有点晕,恩,这就对了,颠颠倒倒嘛。 3、最主要的就是第三个select 语句,他要取从第一条数据到要显示的页的数据,可见越是后面的记录,top n 就会越大,所以这里提取的数据就要做一个精简,只写排序需要的字段(主键字段和排序字段)。 4、第二个select 语句是去掉前面不需要的页里的数据,只保留要显示的页号里的数据。 5、第一个select 语句,用主键字段 in () 的方式提取其他需要的字段。 6、这种分页算法有一个小的bug,就是显示最后一页数据的时候,会多出来几条记录,不过这个bug已经在分页控件里面修正了,最后一页的分页算法,采用特殊的select语句。 7、效率,设置好索引,效率是没有问题的,上一篇随笔已经测试过了。 8、这种算法有一个“侵入性”,就是要求表必须有主键,而且不能是联合主键,引为要用 in 的方式查询数据。但是并没有要求主键自身必须能够排序。
declare @indextable table(id int identity(1,1),nid int) declare @PageLowerBound int declare @PageUpperBound int set @PageLowerBound=(@pageindex-1)*@pagesize set @PageUpperBound=@PageLowerBound+@pagesize set rowcount @PageUpperBound
insert into @indextable(nid) select ProductID from Products where categoryid=3 order by UnitPrice ,ProductID
select * from Products O,@indextable t where O.ProductID=t.nid and t.id between @PageLowerBound+1 and @PageUpperBound order by t.id
显示第3页的数据, 第一次查询需要的时间:6秒, 再次查询:5秒。 内存占用:116M
显示第3000页的数据, 第一次查询需要的时间:28秒, 再次查询:5秒。 内存占用:116M
用了五秒的时间,实在是太慢了!
即使是查可第三页也是花了5秒钟的时间,再次执行相同的语句还是五秒!
=========
select * from Products where ProductID in ( select top 10 ProductID from (select top 30000 ProductID , UnitPrice from Products where CategoryID = 3 order by UnitPrice desc , ProductID ) as aa order by UnitPrice asc, --如果上面是倒序,那么这里就是正序,下同 ProductID desc ) order by UnitPrice desc, --如果上面是倒序,那么这里就是正序,所谓颠颠倒倒嘛。 ProductID
select * from Products where ProductID in ( select top 10 ProductID from (select top 30000 ProductID , UnitPrice from Products --where CategoryID = 3 order by UnitPrice desc , ProductID ) as aa order by UnitPrice asc, --如果上面是倒序,那么这里就是正序,下同 ProductID desc ) order by UnitPrice desc, --如果上面是倒序,那么这里就是正序,所谓颠颠倒倒嘛。 ProductID
declare @indextable table(id int identity(1,1),nid int) declare @PageLowerBound int declare @PageUpperBound int set @PageLowerBound=(@pageindex-1)*@pagesize set @PageUpperBound=@PageLowerBound+@pagesize set rowcount @PageUpperBound
insert into @indextable(nid) select ProductID from Products order by UnitPrice desc,ProductID --where CategoryID = 3
select * from Products O,@indextable t where O.ProductID=t.nid and t.id between @PageLowerBound+1 and @PageUpperBound order by t.id
declare @indextable table(id int identity(1,1),nid int) declare @PageLowerBound int declare @PageUpperBound int set @PageLowerBound=(@pageindex-1)*@pagesize set @PageUpperBound=@PageLowerBound+@pagesize set rowcount @PageUpperBound
insert into @indextable(nid) select ProductID from Products order by ProductID --where CategoryID = 3
select * from Products O,@indextable t where O.ProductID=t.nid and t.id between @PageLowerBound+1 and @PageUpperBound order by t.id
========
declare @col int
select top 29991 @col = ProductID from Products order by ProductID
select top 10 * from Products where ProductID >= @col order by ProductID