July 20, 2007 at 8:00 am
I am trying to create a dataset for a report in "Reporting Services." I need to extract a range of rows from my query. I used "SET ROWCOUNT" to get the first 75 rows, now I need to get the next 75. Does anyone know how to return a range like "ROWS (75-150)"?????
July 23, 2007 at 12:29 pm
That is something you will have to take care of yourself.
Using that last offset of the primary key and the TOP statement can help you out.
July 24, 2007 at 8:11 am
I've come across this issue quite often and have developed a workaround (*hack*) by using a stored procedure to load the data into a temp table that has the first column defined as an identity column that I like to call ROWCOUNT. Once you have all of the data loaded into the temp table in the order you want, you can get ROWCOUNT BETWEEN 1 AND 75, ROWCOUNT BETWEEN 76 AND 150, etc.
Hope that helps.
July 24, 2007 at 8:44 am
Good workaround, but a bit slow and resource intensive if you have millions of rows...
Something like the following works very fast... yeah, it does use dynamic SQL but that's only because I'm still using SQL Server 2000...
The following code will return Page 1 in about 16 milliseconds and Page 12,000 (1.2 million rows later) in about 400-500 milliseconds...
declare @start datetime
set @start = getdate()
--===== Declare the local variables
DECLARE @PageSize INT --How many rows to appear per page
DECLARE @PageNum INT --What page number to appear
DECLARE @Skip INT --Working variable for where to start for page
DECLARE @sql VARCHAR(8000) --Holds dynamic SQL
--===== Set the local variables for pagesize and page
-- PageSize and PageNum would be parameters in a stored proc
SET @PageSize = 100
SET @PageNum = 4000
SET @Skip = @PageSize*@PageNum
--===== Create the dynamic SQL statement that will produce the page
SET @sql =
'
SELECT c.*
FROM dbo.Customer c,
(
SELECT TOP '+STR(@PageSize)+ ' *
FROM dbo.Customer WITH (NOLOCK)
WHERE CustID NOT IN (SELECT TOP '+STR(@Skip)+' CustID
FROM dbo.Customer
ORDER BY CustID)
ORDER BY CustID
) d
WHERE c.CustID = d.CustID
'
--===== Produce the page
EXEC (@SQL)
print CONVERT(varchar(30),getdate()-@start,114)
I'm hoping to see someone use the "new" rownumber function for this... that should actually be much faster...
--Jeff Moden
Change is inevitable... Change for the better is not.
July 24, 2007 at 8:47 am
Thanks for all of your advice. You put me on the right track.
July 24, 2007 at 9:21 am
Unfortunaly the ROW_NUMBER function is a 'Windowed function' and can only be used in the SELECT and ORDER BY clauses ....
It may still be possible to make that work somehow, but it's past my knowledge.
July 25, 2007 at 12:42 am
One option would be to add the number of rows to be displayed in the report as a parameter and then use "TOP" to return only the number of rows requested?
Normally paging/pagination is handled by the report (e.g. reporting services takes all of the rows returned figures out the pagination, and generates a report X number of pages long) so I'm wondering what you're trying to accomplish by short circuiting the process?
Joe
July 25, 2007 at 12:50 am
This link demonstrates the usage of Rank Function for SQL Server 2005 paging technique.
Pinal Dave
sqlauthority.com
July 25, 2007 at 9:55 am
Check Inside Microsoft SQL Server 2005 T-SQL Querying by Itzik Ben-Gan - there are a few solution for this issue, some for 2000, some for 2005.
July 25, 2007 at 6:34 pm
Guess you can't actually look into a book on Amazon anymore, huh
--Jeff Moden
Change is inevitable... Change for the better is not.
August 6, 2007 at 10:54 am
Look up Common Table Expressions (CTE) in books online. They give example of how you can do paging by using a CTE. I have seen some things that say that CTE's have efficiency problems (at least with hierarchy work) but I have had no problems, and they really do make it easier to do paging (which is what it sounds like you want to do.
The basic syntax is:
Viewing 11 posts - 1 through 10 (of 10 total)
You must be logged in to reply to this topic. Login to reply