views:

1591

answers:

9

I have this query with mysql :

select * from table1 LIMIT 10,20

How can I do this with Microsoft sql ?

A: 
SELECT TOP 10 * FROM table;

Is the same as

SELECT * FROM table LIMIT 0,10;

Here's an article about implementing Limit in MsSQL Its a nice read, specially the comments.

Ólafur Waage
Thanks, but I want the record between 10 and 20, there's a way to do it?
Bigballs
this _only ever_ gets the rows from the start of the result set...
mieze
+3  A: 

Clunky, but it'll work.

SELECT TOP 10 * FROM table WHERE id NOT IN (SELECT TOP 10 id FROM table ORDER BY id) FROM table ORDER BY id

MSSQL's omission of a LIMIT clause is criminal, IMO. You shouldn't have to do this kind of kludgy workaround.

ceejayoz
Do you have another suggestion to bypass this?
Bigballs
I did a lot of Googling the last time I had to deal with MSSQL and this was the best solution I found. Not pleasant, but it works.
ceejayoz
This solution works only if the result set includes a column that is unique. It's not a general solution to mimic LIMIT for any query.
Bill Karwin
I'm in a similar quandary right now... However, in my case I'm hosed... It's even more criminal when so called 'expert' dba's decide that an unique key in unnecessary in a table... ANY table...Don't even bring up the subject of foreign keys and constraints!
Andrew Rollings
@Bill Karwin - Good point.
ceejayoz
Problem with this one is, it doesn't handle WHERE clauses very well... I'm going to try temp tables, as its not working for me.
mieze
+9  A: 

Starting SQL SERVER 2005, you can do this...

USE AdventureWorks;
GO
WITH OrderedOrders AS
(
    SELECT SalesOrderID, OrderDate,
    ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber'
    FROM Sales.SalesOrderHeader 
) 
SELECT * 
FROM OrderedOrders 
WHERE RowNumber BETWEEN 10 AND 20;

or something like this for 2000 and below versions...

SELECT TOP 10 * FROM (SELECT TOP 20 FROM Table ORDER BY Id) ORDER BY Id DESC
Leon Tayson
I edited this only to apply code-formatting to the code.
Bill Karwin
The 2nd query fails if you have e.g. 14 rows in the table. It gives you rows 5 through 14, but you want rows 11 through 14. In general, it fails for the last "page" of a result, unless the total rows are a multiple of that "page" size.
Bill Karwin
You're right... haven't tested it :)
Leon Tayson
I struggled quite a bit trying to emulate LIMIT in MS SQL Server when I was developing the Zend Framework. :-)
Bill Karwin
A: 

If i remember correctly (it's been a while since i dabbed with SQL Server) you may be able to use something like this: (2005 and up)

SELECT
    *
   ,ROW_NUMBER() OVER(ORDER BY SomeFields) AS [RowNum]
FROM SomeTable
WHERE RowNum BETWEEN 10 AND 20
Kris
+4  A: 

This is almost a duplicate of a question I asked in October: http://stackoverflow.com/questions/216673/emulate-mysql-limit-clause-in-microsoft-sql-server-2000

If you're using Microsoft SQL Server 2000, there is no good solution. Most people have to resort to capturing the result of the query in a temporary table with a IDENTITY primary key. Then query against the primary key column using a BETWEEN condition.

If you're using Microsoft SQL Server 2005 or later, you have a ROW_NUMBER() function, so you can get the same result but avoid the temporary table.

SELECT t1.*
FROM (
    SELECT ROW_NUMBER OVER(ORDER BY id) AS row, t1.*
    FROM ( ...original SQL query... ) t1
) t2
WHERE t2.row BETWEEN @offset+1 AND @offset+@count;

You can also write this as a common table expression as shown in @Leon Tayson's answer.

Bill Karwin
ROW_NUMBER() OVER (ORDER BY) gets points for being valid in ANSI SQL:2003, although support in DBMSs other than SQL Server is very spotty. And it's pretty clunky of course...
bobince
@bobince: It turns out Oracle, Microsoft SQL Server 2005, IBM DB2, and PostgreSQL 8.4 all support window functions. That covers an huge majority of the SQL market. Support is only spotty if you use MySQL, SQLite or an old version of the DB's above.
Bill Karwin
+2  A: 
SELECT *
FROM   (
       SELECT TOP 20
              t.*, ROW_NUMBER() OVER (ORDER BY field1) AS rn
       FROM   table1 t
       ) to
WHERE rn > 10
Quassnoi
I expect this is the best solution. +1
Bill Karwin
Well, I just checked, SQL Server turned out to be smart enough to stop on ROW_NUMBER() conditions, if there is an indexed column in ORDER BY clause.
Quassnoi
A: 

limit 10, 20 is not standard SQL

cherouvim
No, but it's tremendously useful SQL. What's your point?
ceejayoz
@cherouvim: Your statement is true, but it does not help to answer the question.
Bill Karwin
+1  A: 

This is a multi step approach that will work in SQL2000.

-- Create a temp table to hold the data
CREATE TABLE #foo(rowID int identity(1, 1), myOtherColumns)

INSERT INTO #foo (myColumns) SELECT myData order By MyCriteria

Select * FROM #foo where rowID > 10
souLTower
A: 

USE AdventureWorks;

GO

DECLARE @TOTALROWS int

WITH OrderedOrders AS

(

SELECT SalesOrderID, OrderDate,
ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber'
FROM Sales.SalesOrderHeader 
SET @TOTALROWS = @@rowcount

)

SELECT * FROM OrderedOrders WHERE RowNumber BETWEEN 10 AND 20;

This is not working any help