The ProblemWhere I work, we have a few databases with some pretty large tables. Record counts into the hundreds of thousands are a dime a dozen, and you'll even encounter the occasional table with multiple millions or records. Though I dearly love the SQL keyword TOP, sometimes it is inadequate. As a web programmer, how often have I wished that there were a way to tell a SQL Server to only return rows 50 to 100? Doing so would make result pagination a breeze.
I posted a question to a Cold Fusion Message Board that I frequently visit, and my main man Lance M. (
http://www.webasics.net/) came to the rescue by posting three possible solutions that he had read about in a SQL book.
The SolutionWhile there doesn't really appear to be a way to specify which results to return short of using a stored procedure, there are several possible workarounds. The workaround that I liked best is both simple and elegant. I will post it here. If you are dieing (spelling?) to know the other two, make a comment, and I will post them as well
If you want to get records 1-50 from the fictitious table "author" you would, of course, just do the following:
SELECT TOP 50 *
FROM author
ORDER BY last_name;
However, if you wanted to get records 51-100, you can do this:
---------------------------
SELECT TOP 50 *
FROM
(SELECT TOP 100 *
FROM author
ORDER BY last_name ASC)
ORDER BY last_name DESC;
---------------------------
Presto! What you end up with is records 51-100 (albeit in reverse alphabetical order). This query essentially gets the first hundred authors, reverse alphabetizes them (ORDER BY last_name DESC), and then returns the first 50 from the upside down result. Granted, this method is not as efficient as just being able to specify a STARTROW and an ENDROW, but it is a LOT more efficient than having the database return a coupl'a hundred thousand records, and then just picking out the chunk of 50 that you want.
If you want to re-alphabetize the result, just add the following wrapper:
---------------------------
SELECT *
FROM
(SELECT TOP 50 *
FROM
(SELECT TOP 100 *
FROM author
ORDER BY last_name ASC)
ORDER BY last_name DESC)
ORDER BY last_name ASC;
----------------------------
Very cool, Lance. Thanks for the tip.
3 comments:
What you really want to do is use the OFFSET keyword in the SQL query.
Misaneroth,
Thanks for taking the time to read and post. You bring up a good point.
I apologize for not being more specific. I am looking for the best way to do it without using stored procedures, temporary tables, identity(int, 1, 1) & BETWEEN , or programatic solutions.
Incidentally, if you know of a better way to do it using just a simple SQL SELECT statement, please let me know. I will gladly post it to my blog and give you full credit.
Thanks again,
-N
Great tip man!!!!
Thanks
Post a Comment