sql数据库用row_number函数分页的例子

发布时间:2020-12-14编辑:脚本学堂
有关sql server数据库中row_number函数分页查询的例子,sql分页查询效率优化分析,需要的朋友参考下。

sql server数据库分页查询优化:

1、进行多张表连接,在数据库中先做了一个视图,把表连接起来。
(但是这样查询速度和直接在sql语句中写表连接差不多,但是如果把表连接写在视图中,程序中的sql语句将变得简洁,思路更清晰)
建立视图的sql语句如下:视图名为searchJCR
 

复制代码 代码示例:
SELECT     dbo.JCR_Table.JournalID, dbo.JCR_Table.JournalFullTitle, dbo.JCR_Table.JournalISOTitle, dbo.JCR_Table.JournalJCRTitle,  
 dbo.JCR_Table.JournalISSN, dbo.JCR_Table.JournalLanguage, dbo.JCR_Table.JournalUpdateYear, dbo.SubjectCategories.TotalJouranls,  
 dbo.SubjectCategories.JournalRank, dbo.SubjectCategories.JournalQuartile, dbo.JCRCategory_Table.CategoriesEName,  
 dbo.JCRCategory_Table.CategoriesCName, dbo.JCRIF_Table.YearNum, dbo.JCRIF_Table.IFScore, dbo.JCRCategory_Table.CategoriesID 
FROM         dbo.JCR_Table INNER JOIN 
 dbo.JCRIF_Table ON dbo.JCR_Table.JournalID = dbo.JCRIF_Table.JournalID INNER JOIN 
 dbo.SubjectCategories ON dbo.JCR_Table.JournalID = dbo.SubjectCategories.JournalID AND  
 dbo.SubjectCategories.YearNum = dbo.JCRIF_Table.YearNum INNER JOIN 
 dbo.JCRCategory_Table ON dbo.SubjectCategories.CategoriesID = dbo.JCRCategory_Table.CategoriesID 

2、在程序中使用传统方法进行分页
问题,使用的视图查询出来的结果又很多JournalID重复的记录,这样使用JournalID进行分页就不可行了。

因此,需要为每一条查询记录指定唯一一个标识,在oracle中有伪列rowid,可以用于区分每一条记录,在sql server2005之前,没有办法区分,但是在sql2005之后,提供了一个ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN)函数用于实现类似于伪列的效果。

3、在程序中使用row_number()over()进行分页

sql语句:
 

复制代码 代码示例:
select top 20 * from (select row_number()over(order by YearNum DESC,JournalID ASC) as rowid,sJCR.* from searchJCR as sJCR)where rowid not in(select top 20*queryPage  rowid from (select row_number()over(order by YearNum DESC,JournalID ASC) as rowid,sJCR1.* from searchJCR as sJCR1) where 1=1 and ...) and 1=1 and... order by YearNumDESC,JournalID ASC 


查询速度很慢。

优化(CTE,关于CTE的介绍将读者参阅《SQL Server2005杂谈(1):使用公用表表达式(CTE)简化嵌套SQL》),优化后的代码:
 

复制代码 代码示例:

with t_rowtable  
as
(
    select row_number()over(order by YearNum DESC,JournalID ASC) as row_number,* from [JournalDB].[dbo].[searchJCR] where 1=1

)
select * from t_rowtable where row_number>100
 and row_number <= 60000
 

row_number函数的用途是非常广泛,这个函数的功能是为查询出来的每一行记录生成一个序号,生成的机制是,按over(排序条件)中的排序条件对每条记录顺序生成一个rowid,然后将记录按select的order by顺序显示出来。

其中“where row_number>100
 and row_number <= 60000” 可以用来控制每页的显示的记录,可以用来分页,“where row_number>(page-1)*pageSize
 and row_number <= page*pageSize”,并且只需要将筛选记录的条件拼接在where 1=1之后,这样即使上十几万的数据都可以在3s中之内查询出来,效率很高。
 
例如:
row_number列是由row_number函数生成的序号列。在使用row_number函数是要使用over子句选择对某一列进行排序,然后才能生成序号。

实际上,row_number函数生成序号的基本原理是先使用over子句中的排序语句对记录进行排序,然后按着这个顺序生成序号。over子句中的order by子句与SQL语句中的order by子句没有任何关系,这两处的order by 可以完全不同,SQL语句: 
 

复制代码 代码示例:
select row_number() over(order by field2 desc) as row_number,* from t_table order by field1 desc

sql分页查询结果:

row_number函数分页

注意,如果将row_number函数用于分页处理,over子句中的order by 与排序记录的order by 应相同,否则生成的序号可能不是有续的。