Question

I need to select X rows from a table starting at position Y; a specific column is used for ordering the table.

This query almost works:

DECLARE @Index int
DECLARE @Count int

SELECT * FROM
(
    SELECT TOP (@Count) * FROM
    (
        SELECT TOP (@Index + @Count) * FROM Table
        ORDER BY Table.OrderColumn ASC
    ) AS T1
    ORDER BY T1.OrderColumn DESC
) AS T2
ORDER BY T2.OrderColumn ASC

However, if there aren't enough rows in the table (say, the table has 120 rows and I want 50 rows starting from position 100), this query just ignores the starting position and returns the last X rows.

Also, using three levels of SELECTs and ordering strikes me as quite bad performance-wise.

What is the right way to do this?

Was it helpful?

Solution

Here's a variation that may work

DECLARE @Index int = 5403
DECLARE @Count int = 1000

SELECT * FROM
(
    SELECT TOP (@Index + @Count) *,
        ROW_NUMBER() over (order by OrderColumn) as Sequence
    FROM MyTable
    ORDER BY MyTable.OrderColumn ASC
) as T
WHERE Sequence BETWEEN @Index and @Index + @Count - 1
ORDER BY OrderColumn

The derived table (nested query) shouldn't hurt performance. SQL Server will optimize for it. Although it will depend on the what the real query looks like.

OTHER TIPS

If SQL 2012 is used OFFSET clause may be handy, a sample based on AdventureWorks is provided below :-

DECLARE @Index int = 100 DECLARE @Count int = 50

SELECT SalesOrderID, OrderDate, CustomerID, SalesPersonID  
FROM  Sales.SalesOrderHeader 
ORDER BY OrderDate, SalesOrderID 
OFFSET @Index ROWS FETCH NEXT @Count ROWS ONLY;

if it is SQL2008, windows functions with CTE would be helpful, a sample based on AdventureWorks:-

DECLARE @Index int = 100
DECLARE @Count int = 50

;WITH C AS
(
SELECT ROW_NUMBER() OVER( ORDER BY OrderDate,SalesOrderID ) AS rownum,
SalesOrderID, OrderDate, CustomerID, SalesPersonID
FROM Sales.SalesOrderHeader
)
SELECT SalesOrderID, OrderDate, CustomerID, SalesPersonID
FROM C
WHERE rownum BETWEEN @Index + 1  AND @Index + @Count 
ORDER BY rownum;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top