如果您还希望获得结果总数(在进行分页之前),那么在SQL Server 2000、2005、2008、2012中对结果进行分页的最佳方法是(性能明智的)?


#1楼

最终, Microsoft SQL Server 2012发布了,我真的很喜欢它的分页简单性,您不必使用像此处回答的复杂查询。

要获取接下来的10行,只需运行以下查询:

SELECT * FROM TableName ORDER BY id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;

http://technet.microsoft.com/zh-CN/library/gg699618.aspx

使用时要考虑的要点:

  • 使用OFFSET和FETCH子句必须使用ORDER BY。
  • FETCH必须使用OFFSET子句。 您永远都不能使用ORDER BY…FETCH。
  • TOP不能在同一查询表达式中与OFFSET和FETCH组合。

#2楼

您没有指定语言,也没有指定使用哪个驱动程序。 因此,我正在抽象地描述它。

  • 创建一个可滚动的结果集/数据集。 这要求在桌子上有一个主桌子
  • 跳到最后
  • 请求行数
  • 跳到页面的开始
  • 滚动浏览各行,直到页面末尾

#3楼

获取结果总数和分页是两个不同的操作。 为了这个例子,我们假设您正在处理的查询是

SELECT * FROM Orders WHERE OrderDate >= '1980-01-01' ORDER BY OrderDate

在这种情况下,您可以使用以下方法确定结果总数:

SELECT COUNT(*) FROM Orders WHERE OrderDate >= '1980-01-01'

...这似乎效率低下,但实际上假设所有索引等均已正确设置,性能相当不错。

接下来,要以分页的方式获取实际结果,以下查询将是最有效的:

SELECT  *
FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum, *FROM      OrdersWHERE     OrderDate >= '1980-01-01') AS RowConstrainedResult
WHERE   RowNum >= 1AND RowNum < 20
ORDER BY RowNum

这将返回原始查询的1-19行。 这里最酷的事情是,尤其是对于Web应用程序,您无需保留任何状态,除了要返回的行号。


#4楼

在http://www.codeproject.com/KB/aspnet/PagingLarge.aspx上可以很好地了解不同的分页技术。

我在SQL Server 2000上经常使用ROWCOUNT方法(与ROW_NUMBER相比也可以在2005&2008上使用),闪电般快速,但是您需要确保已排序的列(主要是)的唯一值。


#5楼

MSDN:ROW_NUMBER(Transact-SQL)

返回结果集分区中一行的序号,从每个分区中第一行的1开始。

下面的示例按OrderDate的顺序返回编号为50到60的行。

WITH OrderedOrders AS
(SELECTROW_NUMBER() OVER(ORDER BY FirstName DESC) AS RowNumber, FirstName, LastName, ROUND(SalesYTD,2,1) AS "Sales YTD"FROM [dbo].[vSalesPerson]
)
SELECT RowNumber, FirstName, LastName, Sales YTD
FROM OrderedOrders
WHERE RowNumber > 50 AND RowNumber < 60;
  RowNumber FirstName    LastName               SalesYTD--- -----------  ---------------------- -----------------1   Linda        Mitchell               4251368.542   Jae          Pak                    4116871.223   Michael      Blythe                 3763178.174   Jillian      Carson                 3189418.365   Ranjit       Varkey Chudukatil      3121616.326   José         Saraiva                2604540.717   Shu          Ito                    2458535.618   Tsvi         Reiter                 2315185.619   Rachel       Valdez                 1827066.7110  Tete         Mensa-Annan            1576562.1911  David        Campbell               1573012.9312  Garrett      Vargas                 1453719.4613  Lynn         Tsoflias               1421810.9214  Pamela       Ansman-Wolfe           1352577.13

#6楼

令人难以置信的是,没有其他答案提到在所有SQL Server版本中进行分页的最快方法。 对于较大的页码,胶印可能非常慢,如此处基准所示 。 在SQL中有一种完全不同的,更快的方法来执行分页。 如本博客文章中所述, 这通常称为“搜索方法”或“键集分页”。

SELECT TOP 10 first_name, last_name, score, COUNT(*) OVER()
FROM players
WHERE (score < @previousScore)OR (score = @previousScore AND player_id < @previousPlayerId)
ORDER BY score DESC, player_id DESC

“寻找谓词”

@previousScore@previousPlayerId值是上一页中最后一条记录的相应值。 这使您可以获取“下一页”页面。 如果ORDER BY方向为ASC ,则只需使用>即可。

使用上述方法,您必须先获取前40条记录,才能立即跳至第4页。 但是通常,您还是不想跳得那么远。 相反,您将获得一个更快的查询,该查询可能能够在恒定时间内获取数据,具体取决于您的索引编制。 另外,无论基础数据是否发生更改(例如,在第1页上,而在第4页上),您的页面仍保持“稳定”。

例如,这是在Web应用程序中延迟加载更多数据时实现分页的最佳方法。

注意,“搜索方法”也称为键集分页 。

分页前的总记录

COUNT(*) OVER()窗口函数将帮助您计算“分页之前”的总记录数。 如果使用的是SQL Server 2000,则必须对COUNT(*)进行两个查询。


#7楼

   CREATE view vw_sppb_part_listsource as select row_number() over (partition by sppb_part.init_id order by sppb_part.sppb_part_id asc ) as idx, * from (select part.SPPB_PART_ID, 0 as is_rev, part.part_number , part.init_id from t_sppb_init_part part left join t_sppb_init_partrev prev on ( part.SPPB_PART_ID = prev.SPPB_PART_ID )where prev.SPPB_PART_ID is null union select part.SPPB_PART_ID, 1 as is_rev, prev.part_number , part.init_id from t_sppb_init_part part inner join t_sppb_init_partrev prev on ( part.SPPB_PART_ID = prev.SPPB_PART_ID )) sppb_part

当涉及到不同的init_id时,将重新启动idx


#8楼

试试这个方法:

SELECT TOP @offset a.*
FROM (select top @limit b.*, COUNT(*) OVER() totalrows from TABLENAME b order by id asc) a
ORDER BY id desc;

#9楼

用例明智地,以下内容似乎易于使用且快速。 只需设置页码。

use AdventureWorks
DECLARE @RowsPerPage INT = 10, @PageNumber INT = 6;
with result as(
SELECT SalesOrderDetailID, SalesOrderID, ProductID,
ROW_NUMBER() OVER (ORDER BY SalesOrderDetailID) AS RowNum
FROM Sales.SalesOrderDetail
where 1=1
)
select SalesOrderDetailID, SalesOrderID, ProductID from result
WHERE result.RowNum BETWEEN ((@PageNumber-1)*@RowsPerPage)+1
AND @RowsPerPage*(@PageNumber)

也没有CTE

use AdventureWorks
DECLARE @RowsPerPage INT = 10, @PageNumber INT = 6
SELECT SalesOrderDetailID, SalesOrderID, ProductID
FROM (
SELECT SalesOrderDetailID, SalesOrderID, ProductID,
ROW_NUMBER() OVER (ORDER BY SalesOrderDetailID) AS RowNum
FROM Sales.SalesOrderDetail
where 1=1) AS SOD
WHERE SOD.RowNum BETWEEN ((@PageNumber-1)*@RowsPerPage)+1
AND @RowsPerPage*(@PageNumber)

#10楼

从SQL Server 2012开始,我们可以使用OFFSETFETCH NEXT子句实现分页。

对于SQL Server,请尝试以下操作:

在SQL Server 2012中,在ORDER BY子句中添加了一项新功能,以查询集合数据的优化,从而使使用T-SQL编写的任何人以及整个SQL Server中的整个执行计划的数据分页更加轻松。

在T-SQL脚本下方,具有与上一个示例相同的逻辑。

 --CREATING A PAGING WITH OFFSET and FETCH clauses IN "SQL SERVER 2012" DECLARE @PageNumber AS INT, @RowspPage AS INT SET @PageNumber = 2 SET @RowspPage = 10 SELECT ID_EXAMPLE, NM_EXAMPLE, DT_CREATE FROM TB_EXAMPLE ORDER BY ID_EXAMPLE OFFSET ((@PageNumber - 1) * @RowspPage) ROWS FETCH NEXT @RowspPage ROWS ONLY; 

TechNet:使用SQL Server分页查询


#11楼

对于ROW_NUMBER技术,如果没有要使用的排序列,则可以按以下方式使用CURRENT_TIMESTAMP

SELECT TOP 20 col1,col2,col3,col4
FROM (SELECT tbl.col1 AS col1,tbl.col2 AS col2,tbl.col3 AS col3,tbl.col4 AS col4,ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) AS sort_rowFROM dbo.MyTable tbl) AS query
WHERE query.sort_row > 10
ORDER BY query.sort_row

对于超过700,000的表大小搜索,这对我来说效果很好。

这将获取记录11到30。


#12楼

这些是我在SQL Server端分页查询结果的解决方案。 这些方法在SQL Server 2008和2012之间有所不同。此外,我还添加了按一列进行筛选和排序的概念。 当您在Gridview中进行分页,过滤和排序时,它非常有效。

在测试之前,您必须创建一个示例表并在该表中插入一些行:(在现实世界中,您必须考虑表字段来更改Where子句,并且可能在select的主要部分中具有一些联接和子查询)

Create Table VLT
(ID int IDentity(1,1),Name nvarchar(50),Tel Varchar(20)
)
GOInsert INTO VLT
VALUES('NAME' + Convert(varchar(10),@@identity),'FAMIL' + Convert(varchar(10),@@identity))
GO 500000

在所有这些示例中,我要查询每页200行,并且要获取行号为1200的行。

在SQL Server 2008中,可以使用CTE概念。 因此,我为SQL Server 2008+编写了两种查询

-SQL Server 2008以上版本

DECLARE @PageNumber Int = 1200
DECLARE @PageSize INT = 200
DECLARE @SortByField int = 1 --The field used for sort by
DECLARE @SortOrder nvarchar(255) = 'ASC' --ASC or DESC
DECLARE @FilterType nvarchar(255) = 'None' --The filter type, as defined on the client side (None/Contain/NotContain/Match/NotMatch/True/False/)
DECLARE @FilterValue nvarchar(255) = '' --The value the user gave for the filter
DECLARE @FilterColumn int = 1 --The column to wich the filter is applied, represents the column number like when we send the information.SELECT Data.ID,Data.Name,Data.Tel
FROM(  SELECT ROW_NUMBER() OVER( ORDER BY CASE WHEN @SortByField = 1 AND @SortOrder = 'ASC'THEN VLT.ID END ASC,CASE WHEN @SortByField = 1 AND @SortOrder = 'DESC'THEN VLT.ID END DESC,CASE WHEN @SortByField = 2 AND @SortOrder = 'ASC'THEN VLT.Name END ASC,CASE WHEN @SortByField = 2 AND @SortOrder = 'DESC'THEN VLT.Name END ASC,CASE WHEN @SortByField = 3 AND @SortOrder = 'ASC'THEN VLT.Tel END ASC,CASE WHEN @SortByField = 3 AND @SortOrder = 'DESC'THEN VLT.Tel END ASC) AS RowNum,*  FROM VLT WHERE( -- We apply the filter logic hereCASEWHEN @FilterType = 'None' THEN 1-- Name column filterWHEN @FilterType = 'Contain' AND @FilterColumn = 1AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.ID LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'NotContain' AND @FilterColumn = 1AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.ID NOT LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'Match' AND @FilterColumn = 1AND VLT.ID = @FilterValue THEN 1WHEN @FilterType = 'NotMatch' AND @FilterColumn = 1AND VLT.ID <> @FilterValue THEN 1               -- Name column filterWHEN @FilterType = 'Contain' AND @FilterColumn = 2AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.Name LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'NotContain' AND @FilterColumn = 2AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.Name NOT LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'Match' AND @FilterColumn = 2AND VLT.Name = @FilterValue THEN 1WHEN @FilterType = 'NotMatch' AND @FilterColumn = 2AND VLT.Name <> @FilterValue THEN 1         -- Tel column filter   WHEN @FilterType = 'Contain' AND @FilterColumn = 3AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.Tel LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'NotContain' AND @FilterColumn = 3AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.Tel NOT LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'Match' AND @FilterColumn = 3AND VLT.Tel = @FilterValue THEN 1WHEN @FilterType = 'NotMatch' AND @FilterColumn = 3AND VLT.Tel <> @FilterValue THEN 1    END) = 1   ) AS Data
WHERE Data.RowNum > @PageSize * (@PageNumber - 1)AND Data.RowNum <= @PageSize * @PageNumber
ORDER BY Data.RowNumGO

还有SQL Server 2008+中CTE的第二种解决方案

DECLARE @PageNumber Int = 1200
DECLARE @PageSize INT = 200
DECLARE @SortByField int = 1 --The field used for sort by
DECLARE @SortOrder nvarchar(255) = 'ASC' --ASC or DESC
DECLARE @FilterType nvarchar(255) = 'None' --The filter type, as defined on the client side (None/Contain/NotContain/Match/NotMatch/True/False/)
DECLARE @FilterValue nvarchar(255) = '' --The value the user gave for the filter
DECLARE @FilterColumn int = 1 --The column to wich the filter is applied, represents the column number like when we send the information.;WITHData_CTEAS(  SELECT ROW_NUMBER() OVER( ORDER BY CASE WHEN @SortByField = 1 AND @SortOrder = 'ASC'THEN VLT.ID END ASC,CASE WHEN @SortByField = 1 AND @SortOrder = 'DESC'THEN VLT.ID END DESC,CASE WHEN @SortByField = 2 AND @SortOrder = 'ASC'THEN VLT.Name END ASC,CASE WHEN @SortByField = 2 AND @SortOrder = 'DESC'THEN VLT.Name END ASC,CASE WHEN @SortByField = 3 AND @SortOrder = 'ASC'THEN VLT.Tel END ASC,CASE WHEN @SortByField = 3 AND @SortOrder = 'DESC'THEN VLT.Tel END ASC) AS RowNum,*  FROM VLTWHERE( -- We apply the filter logic hereCASEWHEN @FilterType = 'None' THEN 1-- Name column filterWHEN @FilterType = 'Contain' AND @FilterColumn = 1AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.ID LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'NotContain' AND @FilterColumn = 1AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.ID NOT LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'Match' AND @FilterColumn = 1AND VLT.ID = @FilterValue THEN 1WHEN @FilterType = 'NotMatch' AND @FilterColumn = 1AND VLT.ID <> @FilterValue THEN 1               -- Name column filterWHEN @FilterType = 'Contain' AND @FilterColumn = 2AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.Name LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'NotContain' AND @FilterColumn = 2AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.Name NOT LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'Match' AND @FilterColumn = 2AND VLT.Name = @FilterValue THEN 1WHEN @FilterType = 'NotMatch' AND @FilterColumn = 2AND VLT.Name <> @FilterValue THEN 1         -- Tel column filter   WHEN @FilterType = 'Contain' AND @FilterColumn = 3AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.Tel LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'NotContain' AND @FilterColumn = 3AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.Tel NOT LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'Match' AND @FilterColumn = 3AND VLT.Tel = @FilterValue THEN 1WHEN @FilterType = 'NotMatch' AND @FilterColumn = 3AND VLT.Tel <> @FilterValue THEN 1    END) = 1     )SELECT Data.ID,Data.Name,Data.Tel
FROM Data_CTE AS Data
WHERE Data.RowNum > @PageSize * (@PageNumber - 1)AND Data.RowNum <= @PageSize * @PageNumber
ORDER BY Data.RowNum

-SQL Server 2012以上版本

DECLARE @PageNumber Int = 1200
DECLARE @PageSize INT = 200
DECLARE @SortByField int = 1 --The field used for sort by
DECLARE @SortOrder nvarchar(255) = 'ASC' --ASC or DESC
DECLARE @FilterType nvarchar(255) = 'None' --The filter type, as defined on the client side (None/Contain/NotContain/Match/NotMatch/True/False/)
DECLARE @FilterValue nvarchar(255) = '' --The value the user gave for the filter
DECLARE @FilterColumn int = 1 --The column to wich the filter is applied, represents the column number like when we send the information.;WITHData_CTEAS(  SELECT *  FROM VLTWHERE( -- We apply the filter logic hereCASEWHEN @FilterType = 'None' THEN 1-- Name column filterWHEN @FilterType = 'Contain' AND @FilterColumn = 1AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.ID LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'NotContain' AND @FilterColumn = 1AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.ID NOT LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'Match' AND @FilterColumn = 1AND VLT.ID = @FilterValue THEN 1WHEN @FilterType = 'NotMatch' AND @FilterColumn = 1AND VLT.ID <> @FilterValue THEN 1               -- Name column filterWHEN @FilterType = 'Contain' AND @FilterColumn = 2AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.Name LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'NotContain' AND @FilterColumn = 2AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.Name NOT LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'Match' AND @FilterColumn = 2AND VLT.Name = @FilterValue THEN 1WHEN @FilterType = 'NotMatch' AND @FilterColumn = 2AND VLT.Name <> @FilterValue THEN 1         -- Tel column filter   WHEN @FilterType = 'Contain' AND @FilterColumn = 3AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.Tel LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'NotContain' AND @FilterColumn = 3AND ( -- In this case, when the filter value is empty, we want to show everything.VLT.Tel NOT LIKE '%' + @FilterValue + '%'OR@FilterValue = '') THEN 1WHEN @FilterType = 'Match' AND @FilterColumn = 3AND VLT.Tel = @FilterValue THEN 1WHEN @FilterType = 'NotMatch' AND @FilterColumn = 3AND VLT.Tel <> @FilterValue THEN 1    END) = 1         )SELECT Data.ID,Data.Name,Data.Tel
FROM Data_CTE AS Data
ORDER BY CASE WHEN @SortByField = 1 AND @SortOrder = 'ASC'THEN Data.ID END ASC,CASE WHEN @SortByField = 1 AND @SortOrder = 'DESC'THEN Data.ID END DESC,CASE WHEN @SortByField = 2 AND @SortOrder = 'ASC'THEN Data.Name END ASC,CASE WHEN @SortByField = 2 AND @SortOrder = 'DESC'THEN Data.Name END ASC,CASE WHEN @SortByField = 3 AND @SortOrder = 'ASC'THEN Data.Tel END ASC,CASE WHEN @SortByField = 3 AND @SortOrder = 'DESC'THEN Data.Tel END ASC
OFFSET @PageSize * (@PageNumber - 1) ROWS FETCH NEXT @PageSize ROWS ONLY;

#13楼

在sql server 2012中进行分页的最佳方法是在存储过程中使用offset和fetch next。 OFFSET关键字 -如果我们在order by子句中使用offset,则查询将跳过我们在OFFSET n行中指定的记录数。

FETCH NEXT关键字 -当我们仅将Fetch Next与order by子句一起使用时,它将仅返回您要在分页中显示的行数,如果没有Offset,则SQL会生成错误。 这是下面给出的示例。

create procedure sp_paging
(@pageno as int,@records as int
)
as
begin
declare @offsetcount as int
set @offsetcount=(@pageno-1)*@records
select id,bs,variable from salary order by id offset @offsetcount rows fetch Next @records rows only
end

您可以按照以下步骤执行它。

exec sp_paging 2,3

#14楼

 create PROCEDURE SP_Company_List (@pagesize int = -1 ,@pageindex int= 0 ) > AS BEGIN SET NOCOUNT ON; select Id , NameEn from Company ORDER by Id ASC OFFSET (@pageindex-1 )* @pagesize ROWS FETCH NEXt @pagesize ROWS ONLY END GO 

 DECLARE @return_value int EXEC @return_value = [dbo].[SP_Company_List] @pagesize = 1 , > @pageindex = 2 SELECT 'Return Value' = @return_value GO 

#15楼

该位使您能够使用SQL Server和更新版本的MySQL进行分页,并且每行中包含总行数。 使用您的密钥来计算唯一行数。

WITH T AS
(  SELECT TABLE_ID, ROW_NUMBER() OVER (ORDER BY TABLE_ID) AS RN, (SELECT COUNT(TABLE_ID) FROM TABLE) AS TOTAL FROM TABLE (NOLOCK)
)SELECT T2.FIELD1, T2.FIELD2, T2.FIELD3, T.TOTAL
FROM TABLE T2 (NOLOCK)
INNER JOIN T ON T2.TABLE_ID=T.TABLE_ID
WHERE T.RN >= 100
AND T.RN < 200

#16楼

好吧,我在SQL 2000数据库中使用了以下示例查询,它也适用于SQL 2005。 通过使用多列,它为您提供的功能可以动态排序。 我告诉你...这很强大:)

    ALTER PROCEDURE [dbo].[RE_ListingReports_SelectSummary] @CompanyID  int,
@pageNumber     int,
@pageSize   int,
@sort       varchar(200)
ASDECLARE @sql nvarchar(4000)
DECLARE @strPageSize nvarchar(20)
DECLARE @strSkippedRows nvarchar(20)
DECLARE @strFields nvarchar(4000)
DECLARE @strFilter nvarchar(4000)
DECLARE @sortBy nvarchar(4000)
DECLARE @strFrom nvarchar(4000)
DECLARE @strID nvarchar(100)If(@pageNumber < 0)SET @pageNumber = 1
SET @strPageSize = CAST(@pageSize AS varchar(20))
SET @strSkippedRows = CAST(((@pageNumber - 1) * @pageSize) AS varchar(20))-- For    example if pageNumber is 5  pageSize is 10, then SkippedRows = 40.
SET @strID = 'ListingDbID'
SET @strFields = 'ListingDbID,
ListingID,
[ExtraRoom]
'
SET @strFrom = ' vwListingSummary 'SET @strFilter = ' WHERECompanyID = ' + CAST(@CompanyID As varchar(20))
End
SET @sortBy = ''
if(len(ltrim(rtrim(@sort))) > 0)
SET @sortBy = ' Order By ' + @sort-- Total Rows CountSET @sql =  'SELECT Count(' + @strID + ')  FROM ' + @strFROM + @strFilter
EXEC sp_executesql @sql--// This technique is used in a Single Table pagination
SET @sql = 'SELECT ' + @strFields + ' FROM ' + @strFROM +' WHERE ' + @strID +  ' IN ' + '  (SELECT TOP ' + @strPageSize + ' ' + @strID + ' FROM ' + @strFROM + @strFilter + ' AND  ' + @strID + ' NOT IN ' + '(SELECT TOP ' + @strSkippedRows + ' ' + @strID + ' FROM ' + @strFROM + @strFilter + @SortBy + ') ' + @SortBy + ') ' + @SortBy
Print @sql
EXEC sp_executesql @sql

最好的部分是sp_executesql缓存以后的调用,前提是您传递相同的参数,即生成相同的sql文本。


#17楼

对于SQL Server 2000,可以使用带有IDENTITY列的表变量模拟ROW_NUMBER():

DECLARE @pageNo int -- 1 based
DECLARE @pageSize int
SET @pageNo = 51
SET @pageSize = 20DECLARE @firstRecord int
DECLARE @lastRecord int
SET @firstRecord = (@pageNo - 1) * @pageSize + 1 -- 1001
SET @lastRecord = @firstRecord + @pageSize - 1   -- 1020DECLARE @orderedKeys TABLE (rownum int IDENTITY NOT NULL PRIMARY KEY CLUSTERED,TableKey int NOT NULL
)SET ROWCOUNT @lastRecord
INSERT INTO @orderedKeys (TableKey) SELECT ID FROM Orders WHERE OrderDate >= '1980-01-01' ORDER BY OrderDateSET ROWCOUNT 0SELECT t.*
FROM Orders tINNER JOIN @orderedKeys o ON o.TableKey = t.ID
WHERE o.rownum >= @firstRecord
ORDER BY o.rownum

这种方法可以扩展到具有多列键的表,并且不会产生使用OR(跳过索引使用)的性能开销。 不利的一面是,如果数据集非常大且一个数据集位于最后一页附近,则占用的临时空间量。 在那种情况下,我没有测试游标的性能,但是可能会更好。

请注意,可以针对数据的第一页优化此方法。 另外,由于TOP在SQL Server 2000中不接受变量,因此使用了ROWCOUNT。

在SQL Server中分页结果的最佳方法是什么相关推荐

  1. sql server 中 create or replace 视图方法

    sql server 中没有  create or replace 语法,可以用下面的语句: IF EXISTS(SELECT 1 FROM sys.views WHERE name = '视图名称' ...

  2. sql server注入_SQL注入:SQL Server中的介绍和预防方法

    sql server注入 A SQL injection attack is one of the most commonly used hacking techniques. It allows h ...

  3. Sql Server中三种字符串合并方法的性能比较

    最近正在处理一个合并字符吕的存储过程,在一个测试系统的开发中,要使用到字符串合并功能,直接在Sql中做.         示例:         有表內容﹕         名称  內容        ...

  4. 在SQL Server中以运行总计运行

    背景 (Background) Running totals have long been the core of most financial systems, be statements or e ...

  5. sql 会话_在特定会话中禁用SQL Server中的触发器

    sql 会话 This article will focus on the various ways to disable triggers in SQL Server so they won't i ...

  6. sql数据库备份默认路径_在Linux上SQL Server中更改默认数据库文件和备份路径

    sql数据库备份默认路径 In a previous article, we explored the process to change default SQL dump file location ...

  7. 在AWS RDS SQL Server中恢复数据

    This article explores the process to recover data in AWS RDS SQL Server and its recent enhancements. ...

  8. 【转】在SQL Server中通过SQL语句实现分页查询

    在SQL Server中通过SQL语句实现分页查询 2008年01月06日 星期日 12:28 建立表: CREATE TABLE [TestTable] ( [ID] [int] IDENTITY ...

  9. 在SQL Server中配置索引创建内存设置的最佳实践

    介绍 (Introduction) The Index Create Memory setting is an advanced SQL Server configuration setting wh ...

最新文章

  1. Oracle与JCP执行委员会分享了他们的Java EE策略
  2. 发条js调试工具_小工具大帮手,利用 @open-node/antman 实现 node.js 进程线上调试,无须重启...
  3. Windows XP Mode
  4. PPT 2016的加解密功能
  5. 计算机导论的试题,计算机导论试题
  6. Seaborn:Python
  7. Java常见GC算法_垃圾收集器及内存分配_G1垃圾收集器
  8. Skeljs – 用于构建响应式网站的前端开发框架
  9. VINS(二)Feature Detection and Tracking
  10. 用 ElementTree 在 Python 中解析 XML
  11. 奥本海姆信号与系统(第二版)笔记
  12. CodeGym:以游戏化的方式学习Java真的是事半功倍
  13. 基于stm32单片机外文文献_基于STM32的智能家居系统设计毕业论文+任务书+开题报告+文献综述+外文翻译及原文+程序+原理图+参考资料+答辩PPT+仿真设计...
  14. 闽什么什么院第二课堂网课破解-----微信内置浏览器
  15. 用python写模拟鼠标脚本
  16. mysql建立唯一索引升序_MySQL数据库SQL优化技巧六之唯一索引
  17. 爬虫selenium(edge屋头浏览器+规避检测风险)
  18. lol8月21号服务器维护,lol维护到几点今天?英雄联盟LOL8月21日维护更新内容
  19. android 免root 模拟器,真正免root的root工具箱详细使用教程
  20. win10左右声道音量不一致的解决方法

热门文章

  1. 大佬教你极简方法来处理Android SharedPreferences设计与实现
  2. 算法----单链表反转
  3. AndroidStudio2.2 Preview3中NDK开发之CMake和传统 JNI在目录结构和配置文件上的区别
  4. Android之BaseAdapter使用
  5. 【UIKit】文本框(UITextField)及键盘遮挡处理和回收
  6. 开发环境wamp3.06 + Zend studio 12 调试配置
  7. vi使用技巧(转载)
  8. 认识MySQL Replication
  9. java语言基础特性
  10. servlet之控制分发