mssql分页

今天在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

你可能感兴趣的:(sql,C++,c,mysql,Go)