Pagination
Pagination using ROW_NUMBER with a Common Table Expression
Section titled “Pagination using ROW_NUMBER with a Common Table Expression”The ROW_NUMBER function can assign an incrementing number to each row in a result set. Combined with a Common Table Expression that uses a BETWEEN operator, it is possible to create ‘pages’ of result sets. For example: page one containing results 1-10, page two containing results 11-20, page three containing results 21-30, and so on.
WITH dataAS( SELECT ROW_NUMBER() OVER (ORDER BY name) AS row_id, object_id, name, type, create_date FROM sys.objects)SELECT *FROM dataWHERE row_id BETWEEN 41 AND 50Note: It is not possible to use ROW_NUMBER in a WHERE clause like:
SELECT object_id, name, type, create_dateFROM sys.objectsWHERE ROW_NUMBER() OVER (ORDER BY name) BETWEEN 41 AND 50Although this would be more convenient, SQL server will return the following error in this case:
Msg 4108, Level 15, State 1, Line 6 Windowed functions can only appear in the SELECT or ORDER BY clauses.
Pagination with OFFSET FETCH
Section titled “Pagination with OFFSET FETCH”The OFFSET FETCH clause implements pagination in a more concise manner. With it, it’s possible to skip N1 rows (specified in OFFSET) and return the next N2 rows (specified in FETCH):
SELECT *FROM sys.objectsORDER BY object_idOFFSET 40 ROWS FETCH NEXT 10 ROWS ONLYThe ORDER BY clause is required in order to provide deterministic results.
Paginaton with inner query
Section titled “Paginaton with inner query”In earlier versions of SQL Server, developers had to use double sorting combined with the TOP keyword to return rows in a page:
SELECT TOP 10 * FROM ( SELECT TOP 50 object_id, name, type, create_date FROM sys.objects ORDER BY name ASC) AS dataORDER BY name DESCThe inner query will return the first 50 rows ordered by name. Then the outer query will reverse the order of these 50 rows and select the top 10 rows (these will be last 10 rows in the group before the reversal).
Paging in Various Versions of SQL Server
Section titled “Paging in Various Versions of SQL Server”SQL Server 2012 / 2014
Section titled “SQL Server 2012 / 2014”DECLARE @RowsPerPage INT = 10, @PageNumber INT = 4SELECT OrderId, ProductIdFROM OrderDetailORDER BY OrderIdOFFSET (@PageNumber - 1) * @RowsPerPage ROWSFETCH NEXT @RowsPerPage ROWS ONLYSQL Server 2005/2008/R2
Section titled “SQL Server 2005/2008/R2”DECLARE @RowsPerPage INT = 10, @PageNumber INT = 4SELECT OrderId, ProductIdFROM ( SELECT OrderId, ProductId, ROW_NUMBER() OVER (ORDER BY OrderId) AS RowNum FROM OrderDetail) AS ODWHERE OD.RowNum BETWEEN ((@PageNumber - 1 ) * @RowsPerPage) + 1AND @RowsPerPage * @PageNumberSQL Server 2000
Section titled “SQL Server 2000”DECLARE @RowsPerPage INT = 10, @PageNumber INT = 4SELECT OrderId, ProductIdFROM (SELECT TOP (@RowsPerPage) OrderId, ProductId FROM (SELECT TOP ((@PageNumber)*@RowsPerPage) OrderId, ProductId FROM OrderDetail ORDER BY OrderId) AS OD ORDER BY OrderId DESC) AS OD2ORDER BY OrderId ASCSQL Server 2012/2014 using ORDER BY OFFSET and FETCH NEXT
Section titled “SQL Server 2012/2014 using ORDER BY OFFSET and FETCH NEXT”For getting the next 10 rows just run this query:
SELECT * FROM TableName ORDER BY id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;Key points to consider when using it:
ORDER BYis mandatory to useOFFSETandFETCHclause.
Syntax
Section titled “Syntax”- SELECT * FROM TableName ORDER BY id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;