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
I would avoid using SELECT *
. Specify columns you actually want even though it may be all of them.
SQL Server 2005+
SELECT col1, col2
FROM (
SELECT col1, col2, ROW_NUMBER() OVER (ORDER BY ID) AS RowNum
FROM MyTable
) AS MyDerivedTable
WHERE MyDerivedTable.RowNum BETWEEN @startRow AND @endRow
SQL Server 2000
Efficiently Paging Through Large Result Sets in SQL Server 2000
A More Efficient Method for Paging Through Large Result Sets
SELECT TOP 75 * FROM MyTable
EXCEPT
SELECT TOP 50 * FROM MyTable
Depending on your version ou cannot do it directly, but you could do something hacky like
select top 25 *
from (
select top 75 *
from table
order by field asc
) a
order by field desc
where 'field' is the key.
Best way to do it without wasting time to order records is like this :
select 0 as tmp,Column1 from Table1 Order by tmp OFFSET 5000000 ROWS FETCH NEXT 50 ROWS ONLY
it takes less than one second!
best solution for large tables.
You should be careful when using the ROW_NUMBER() OVER (ORDER BY)
statement as performance is quite poor. Same goes for using Common Table Expressions with ROW_NUMBER()
that is even worse. I'm using the following snippet that has proven to be slightly faster than using a table variable with an identity to provide the page number.
DECLARE @Offset INT = 120000
DECLARE @Limit INT = 10
DECLARE @ROWCOUNT INT = @Offset+@Limit
SET ROWCOUNT @ROWCOUNT
SELECT * FROM MyTable INTO #ResultSet
WHERE MyTable.Type = 1
SELECT * FROM
(
SELECT *, ROW_NUMBER() OVER(ORDER BY SortConst ASC) As RowNumber FROM
(
SELECT *, 1 As SortConst FROM #ResultSet
) AS ResultSet
) AS Page
WHERE RowNumber BETWEEN @Offset AND @ROWCOUNT
DROP TABLE #ResultSet
I've been searching for this answer for a while now (for generic queries) and found out another way of doing it on SQL Server 2000+ using ROWCOUNT and cursors and without TOP or any temporary table.
Using the SET ROWCOUNT [OFFSET+LIMIT]
you can limit the results, and with cursors, go directly to the row you wish, then loop 'till the end.
So your query would be like this:
SET ROWCOUNT 75 -- (50 + 25)
DECLARE MyCursor SCROLL CURSOR FOR SELECT * FROM pessoas
OPEN MyCursor
FETCH ABSOLUTE 50 FROM MyCursor -- OFFSET
WHILE @@FETCH_STATUS = 0 BEGIN
FETCH next FROM MyCursor
END
CLOSE MyCursor
DEALLOCATE MyCursor
SET ROWCOUNT 0