views:

4045

answers:

5

I'm trying to do something like :

SELECT * FROM table LIMIT 10,20

or

SELECT * FROM table LIMIT 10 OFFSET 10

but using SQLServer

The only solution I found looks like overkill:

SELECT * FROM ( 
  SELECT *, ROW_NUMBER() OVER (ORDER BY name) as row FROM sys.databases 
 ) a WHERE row > 5 and row <= 10

I also found:

SELECT TOP 10 * FROM stuff;

... but it's not what I want to do since I can't specify the starting limit.

Is there another way for me to do that ?

Also, just curious, is there a reason why doesn't MSserver support the LIMIT function or something similar? I don't want to be mean, but that really sounds like something a DBMS needs ... If it does, then I'm sorry for being so ignorant! I've been working with MySQL and SQL+ for the past 5 years so...

+4  A: 

Unfortunately, the ROW_NUMBER() is the best you can do. It's actually more correct, because the results of a limit or top clause don't really have meaning without respect to some specific order. But it's still a pain to do.

Joel Coehoorn
@Joel: Can you explain why ROW_NUMBER() is unable to number the rows the way they come out of ORDER BY? I've always wondered why the "OVER (ORDER BY name)" is mandatory, but I guess there is a good reason for it. Or at least *a* reason.
Tomalak
because there is no such thing as order without an order by clause. You get whatever order the records were available to the server, and that could _change_ from query request to query request.
Joel Coehoorn
But I was explicitly referring to an ORDER BY clause. Assume the query itself has one - why can't ROW_NUMBER() just just that? I mean, what's the DB-internal reason that forces me to change the query in two places if I want to get a slice of it in a different order?
Tomalak
Interesting. Do you know if Microsoft plans on including the Limit function a release to come of sqlserver?
marcgg
@marcgg: I've never read any indication that Microsoft plans to implement LIMIT. Even if they do have such a plan, closed-source vendors tend not to pre-announce features. It would certainly be a helpful feature, but we don't know how much work it would be to implement, given their code.
Bill Karwin
If you don't want to repeat yourself in the ORDER BY clause, use the ROW_NUMBER() alias rather than the original set of columns.
Peter
@Tomalak: As far as SQL Server is concerned, the ordering used to calculate ROW_NUMBER() is completely unrelated to the ordering of the resultset. That's why you have to specify them separately.
LukeH
+2  A: 

as you found, this is the preferred sql server method:

SELECT * FROM ( 
  SELECT *, ROW_NUMBER() OVER (ORDER BY name) as row FROM sys.databases 
 ) a WHERE row > 5 and row <= 10
KM
A: 
David Patrick
What if there are only 14 rows in the table? You get rows 14 down to 5, which is not the same as rows returned by LIMIT 10 OFFSET 10 (should be rows 14 down to 11).
Bill Karwin
+4  A: 

The LIMIT clause is not part of standard SQL. It's supported as a vendor extension to SQL by MySQL, PostgreSQL, and SQLite.

Other brands of database may have similar features (e.g. TOP in Microsoft SQL Server), but these don't always work identically.

It's hard to use TOP in Microsoft SQL Server to mimic the LIMIT clause. There are cases where it just doesn't work.

The solution you showed, using ROW_NUMBER() is available in Microsoft SQL Server 2005 and later. This is the best solution (for now) that works solely as part of the query.

Another solution is to use TOP to fetch the first count + offset rows, and then use the API to seek past the first offset rows.

See also:

Bill Karwin
A: 

please help me i want to fetch 10 records from table but cindition is that i doesn;t want to fetch top 2 records from table all these things will do with order by publish_date field.

ram