Is there any way in SQL Server to get the results starting at a given offset? For example, in another type of SQL database, it\'s possible to do:
SELECT * FR
There is OFFSET .. FETCH
in SQL Server 2012, but you will need to specify an ORDER BY
column.
If you really don't have any explicit column that you could pass as an ORDER BY
column (as others have suggested), then you can use this trick:
SELECT * FROM MyTable
ORDER BY @@VERSION
OFFSET 50 ROWS FETCH NEXT 25 ROWS ONLY
... or
SELECT * FROM MyTable
ORDER BY (SELECT 0)
OFFSET 50 ROWS FETCH NEXT 25 ROWS ONLY
We're using it in jOOQ when users do not explicitly specify an order. This will then produce pretty random ordering without any additional costs.
I use this technique for pagination. I do not fetch all the rows. For example, if my page needs to display the top 100 rows I fetch only the 100 with where clause. The output of the SQL should have a unique key.
The table has the following:
ID, KeyId, Rank
The same rank will be assigned for more than one KeyId.
SQL is select top 2 * from Table1 where Rank >= @Rank and ID > @Id
For the first time I pass 0 for both. The second time pass 1 & 14. 3rd time pass 2 and 6....
The value of the 10th record Rank & Id is passed to the next
11 21 1
14 22 1
7 11 1
6 19 2
12 31 2
13 18 2
This will have the least stress on the system
You can use ROW_NUMBER()
function to get what you want:
SELECT *
FROM (SELECT ROW_NUMBER() OVER(ORDER BY id) RowNr, id FROM tbl) t
WHERE RowNr BETWEEN 10 AND 20
This is one way (SQL2000)
SELECT * FROM
(
SELECT TOP (@pageSize) * FROM
(
SELECT TOP (@pageNumber * @pageSize) *
FROM tableName
ORDER BY columnName ASC
) AS t1
ORDER BY columnName DESC
) AS t2
ORDER BY columnName ASC
and this is another way (SQL 2005)
;WITH results AS (
SELECT
rowNo = ROW_NUMBER() OVER( ORDER BY columnName ASC )
, *
FROM tableName
)
SELECT *
FROM results
WHERE rowNo between (@pageNumber-1)*@pageSize+1 and @pageNumber*@pageSize
Following will display 25 records excluding first 50 records works in SQL Server 2012.
SELECT * FROM MyTable ORDER BY ID OFFSET 50 ROWS FETCH NEXT 25 ROWS ONLY;
you can replace ID as your requirement
If you will be processing all pages in order then simply remembering the last key value seen on the previous page and using TOP (25) ... WHERE Key > @last_key ORDER BY Key
can be the best performing method if suitable indexes exist to allow this to be seeked efficiently - or an API cursor if they don't.
For selecting an arbitary page the best solution for SQL Server 2005 - 2008 R2 is probably ROW_NUMBER
and BETWEEN
For SQL Server 2012+ you can use the enhanced ORDER BY clause for this need.
SELECT *
FROM MyTable
ORDER BY OrderingColumn ASC
OFFSET 50 ROWS
FETCH NEXT 25 ROWS ONLY
Though it remains to be seen how well performing this option will be.