在SQL Server中分页结果的最佳方法是什么
如果您还希望获得结果总数(在进行分页之前),那么在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开始,我们可以使用OFFSET
和FETCH 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中分页结果的最佳方法是什么相关推荐
- sql server 中 create or replace 视图方法
sql server 中没有 create or replace 语法,可以用下面的语句: IF EXISTS(SELECT 1 FROM sys.views WHERE name = '视图名称' ...
- sql server注入_SQL注入:SQL Server中的介绍和预防方法
sql server注入 A SQL injection attack is one of the most commonly used hacking techniques. It allows h ...
- Sql Server中三种字符串合并方法的性能比较
最近正在处理一个合并字符吕的存储过程,在一个测试系统的开发中,要使用到字符串合并功能,直接在Sql中做. 示例: 有表內容﹕ 名称 內容 ...
- 在SQL Server中以运行总计运行
背景 (Background) Running totals have long been the core of most financial systems, be statements or e ...
- sql 会话_在特定会话中禁用SQL Server中的触发器
sql 会话 This article will focus on the various ways to disable triggers in SQL Server so they won't i ...
- sql数据库备份默认路径_在Linux上SQL Server中更改默认数据库文件和备份路径
sql数据库备份默认路径 In a previous article, we explored the process to change default SQL dump file location ...
- 在AWS RDS SQL Server中恢复数据
This article explores the process to recover data in AWS RDS SQL Server and its recent enhancements. ...
- 【转】在SQL Server中通过SQL语句实现分页查询
在SQL Server中通过SQL语句实现分页查询 2008年01月06日 星期日 12:28 建立表: CREATE TABLE [TestTable] ( [ID] [int] IDENTITY ...
- 在SQL Server中配置索引创建内存设置的最佳实践
介绍 (Introduction) The Index Create Memory setting is an advanced SQL Server configuration setting wh ...
最新文章
- Oracle与JCP执行委员会分享了他们的Java EE策略
- 发条js调试工具_小工具大帮手,利用 @open-node/antman 实现 node.js 进程线上调试,无须重启...
- Windows XP Mode
- PPT 2016的加解密功能
- 计算机导论的试题,计算机导论试题
- Seaborn:Python
- Java常见GC算法_垃圾收集器及内存分配_G1垃圾收集器
- Skeljs – 用于构建响应式网站的前端开发框架
- VINS(二)Feature Detection and Tracking
- 用 ElementTree 在 Python 中解析 XML
- 奥本海姆信号与系统(第二版)笔记
- CodeGym:以游戏化的方式学习Java真的是事半功倍
- 基于stm32单片机外文文献_基于STM32的智能家居系统设计毕业论文+任务书+开题报告+文献综述+外文翻译及原文+程序+原理图+参考资料+答辩PPT+仿真设计...
- 闽什么什么院第二课堂网课破解-----微信内置浏览器
- 用python写模拟鼠标脚本
- mysql建立唯一索引升序_MySQL数据库SQL优化技巧六之唯一索引
- 爬虫selenium(edge屋头浏览器+规避检测风险)
- lol8月21号服务器维护,lol维护到几点今天?英雄联盟LOL8月21日维护更新内容
- android 免root 模拟器,真正免root的root工具箱详细使用教程
- win10左右声道音量不一致的解决方法