现在的位置: 首页 > 综合 > 正文

mssql分页

2012年07月31日 ⁄ 综合 ⁄ 共 4338字 ⁄ 字号 评论关闭

今天在ms sql 里想弄个分页,可是发现mssql 里是没 mysql 里的 limit 函数的,于是在网上找了一些解决的方法,发现这样可以做到。。。

 

mySql 输入:   
  select   *   from   table_news   order   by   news_id   desc   limit   5,4    
ms Sql 输出:  
 
select   *   from   (   select   top   4   *   from   (   select   top  
9   *   from   table_news   order   by   news_id   desc   )   as  
totleResult   order   by   news_id   )   as   allResult   order   by  
news_id   desc



 

其实可以这样认为 vPagesize=10, vPageNo=2, 语句就可以写成:

"select   *   from   (  
select   top  "  +vPagesize+ "   *   from   (   select   top   " +
int.Parse(vPageNo * vPagesize) +"   *   from   chenhua_news   order   by
  news_id   desc   )   as   totleResult   order   by  
news_id /*要注意这里是没有desc的*/  )   as   allResult   order   by   news_id  
desc



 

*** 例如我今天写的: 这里的 10 就是指一页显示10条记录, 40 是指这里读取第4页的数据, 而这里还有一个条件就是以c开头的记录 like 'c%'

select vendno,company ,(select count(*) from cust0001 where ltrim(rtrim(status))='U') as countRecords from
 ( select top 10 vendno,company from (select top 40
vendno,company from cust0001 where ltrim(rtrim(status))='U' and company like 'c%' order by company )
as totleResult order by company desc) as allResult
 order by company

 

 

 

建立表:

 

CREATE TABLE [TestTable] (

[ID] [int] IDENTITY (1, 1) NOT NULL ,

[FirstName] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NULL ,

[LastName] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NULL ,

[Country] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,

[Note] [nvarchar] (2000) COLLATE Chinese_PRC_CI_AS NULL

) ON [PRIMARY]

GO

插入数据


:(2万条,用更多的数据测试会明显一些)

SET IDENTITY_INSERT TestTable ON



declare @i int

set @i=1

while @i<=20000

begin

insert into TestTable([id], FirstName, LastName, Country,Note)

values(@i, 'FirstName_XXX','LastName_XXX','Country_XXX','Note_XXX')

set @i=@i+1

end



SET IDENTITY_INSERT TestTable OFF

分页方案一:

(利用Not In和SELECT TOP分页)

语句形式:

SELECT TOP 10 *

FROM TestTable

WHERE (ID NOT IN

(SELECT TOP 20 id

FROM TestTable

ORDER BY id))

ORDER BY ID





SELECT TOP 页大小 *

FROM TestTable

WHERE (ID NOT IN

(SELECT TOP 页大小*页数 id

FROM 表

ORDER BY id))

ORDER BY ID

分页方案二:

(利用ID大于多少和SELECT TOP分页)

语句形式:

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


的游标存储


过程分页)

create  procedure XiaoZhengGe

@sqlstr nvarchar(4000), --查询字符串

@currentpage int, --第N页

@pagesize int --每页行数

as

set nocount on

declare @P1 int, --P1是游标的id

@rowcount int

exec sp_cursoropen @P1 output,@sqlstr,

@scrollopt=1,@ccopt=1,@rowcount=@rowcount output

select ceiling(1.0*@rowcount/@pagesize)

as 总页数--,@rowcount as 总行数,@currentpage as 当前页

set @currentpage=(@currentpage-1)*@pagesize+1

exec sp_cursorfetch @P1,16,@currentpage,@pagesize

exec sp_cursorclose @P1

set nocount off

其它的方案:如果没有主键,可以用临时表,也可以用方案三做,但是效率会低。

建议优化的时候,加上主键和索引,查询效率会提高。

通过SQL 查询分析器,显示比较:我的结论是:

分页方案二:(利用ID大于多少和SELECT TOP分页)效率最高,需要拼接SQL语句。

分页方案一:(利用Not In和SELECT TOP分页)效率次之,需要拼接SQL语句。

分页方案三:(利用SQL的游标存储过程分页)效率最差,但是最为通用。

建立表:

CREATE TABLE [TestTable] (

[ID] [int] IDENTITY (1, 1) NOT NULL ,

[FirstName] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NULL ,

[LastName] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NULL ,

[Country] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,

[Note] [nvarchar] (2000) COLLATE Chinese_PRC_CI_AS NULL

) ON [PRIMARY]

GO

插入数据:(2万条,用更多的数据测试会明显一些)

SET IDENTITY_INSERT TestTable ON



declare @i int

set @i=1

while @i<=20000

begin

insert into TestTable([id], FirstName, LastName, Country,Note)

values(@i, 'FirstName_XXX','LastName_XXX','Country_XXX','Note_XXX')

set @i=@i+1

end



SET IDENTITY_INSERT TestTable OFF

分页方案一:

(利用Not In和SELECT TOP分页)

语句形式:

SELECT TOP 10 *

FROM TestTable

WHERE (ID NOT IN

(SELECT TOP 20 id

FROM TestTable

ORDER BY id))

ORDER BY ID





SELECT TOP 页大小 *

FROM TestTable

WHERE (ID NOT IN

(SELECT TOP 页大小*页数 id

FROM 表

ORDER BY id))

ORDER BY ID

分页方案二:

(利用ID大于多少和SELECT TOP分页)

语句形式:

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的游标存储过程分页)

create  procedure XiaoZhengGe

@sqlstr nvarchar(4000), --查询字符串

@currentpage int, --第N页

@pagesize int --每页行数

as

set nocount on

declare @P1 int, --P1是游标的id

@rowcount int

exec sp_cursoropen @P1 output,@sqlstr,

@scrollopt=1,@ccopt=1,@rowcount=@rowcount output

select ceiling(1.0*@rowcount/@pagesize)

as 总页数--,@rowcount as 总行数,@currentpage as 当前页

set @currentpage=(@currentpage-1)*@pagesize+1

exec sp_cursorfetch @P1,16,@currentpage,@pagesize

exec sp_cursorclose @P1

set nocount off

其它的方案:如果没有主键,可以用临时表,也可以用方案三做,但是效率会低。

建议优化的时候,加上主键和索引,查询效率会提高。

通过SQL 查询分析器,显示比较:我的结论是:

分页方案二:(利用ID大于多少和SELECT TOP分页)效率最高,需要拼接SQL语句。

分页方案一:(利用Not In和SELECT TOP分页)效率次之,需要拼接SQL语句。

分页方案三:(利用SQL的游标存储过程分页)效率最差,但是最为通用。

SQLServer:
select * from
(
select top @pageSize * from
(
    select top (@pageSize*@currentPage) * from page order by _id asc
)t1 order by _id desc
)t2 order by _id asc

 

抱歉!评论已关闭.