I want to fire a Query "SELECT * FROM TABLE
" but select only from row N+1
. Any idea on how to do this?

- 15,573
- 16
- 56
- 75

- 837
- 1
- 6
- 7
-
4Which rdbms are you using(f.e. oracle, mysql or sql-server)? – Tim Schmelter Apr 27 '15 at 11:38
-
6Which dbms? "OFFSET n" is ANSI SQL, but many dbms products do this in their own ways, eg. LIMIT, TOP... – jarlh Apr 27 '15 at 11:38
-
1Also, if you want to find rows in a given row-number range you could use functions like [`ROW_NUMBER`](https://msdn.microsoft.com/en-us/library/ms186734.aspx). But that really depends on your dbms. – Tim Schmelter Apr 27 '15 at 11:40
-
Check ROW_NUMBER (). – George T Apr 27 '15 at 11:41
-
(a) In Relational Databases (ie. those that comply with the *Relational Model*), the rows are *not* ordered, any ordering that may be required in explicitly declared by the calling code via `ORDER BY …` (b) We don't have row numbers or `ROW_NUMBER(),` which is actually a **Record ID**. These are physical record (not row) locators, the *RM* demands logical Keys. (c) Therefore, in an RDb, your question does not exist, we `SELECT … WHERE Key >= "value".` It exists in Record Filing Systems, that have none of the Integrity, Power, or Speed of an RDb. – PerformanceDBA Apr 28 '15 at 02:25
14 Answers
For SQL Server 2012 and above, use this:
SELECT *
FROM Sales.SalesOrderHeader
ORDER BY OrderDate
OFFSET (@Skip) ROWS FETCH NEXT (@Take) ROWS ONLY

- 2,665
- 3
- 24
- 46
-
7
-
3Also note the that the 'new' syntax strangely have a performance penalty linear with the @skip over the row_number approach (indexed order clause). On the other hand the syntax have the great benefit of being a pure appendage, so any script generated by something, ending with an order clause, can have this appended. – Eske Rahn Jun 24 '18 at 14:33
SQL Server:
select * from table
except
select top N * from table
Oracle up to 11.2:
select * from table
minus
select * from table where rownum <= N
with TableWithNum as (
select t.*, rownum as Num
from Table t
)
select * from TableWithNum where Num > N
Oracle 12.1 and later (following standard ANSI SQL)
select *
from table
order by some_column
offset x rows
fetch first y rows only
They may meet your needs more or less.
There is no direct way to do what you want by SQL. However, it is not a design flaw, in my opinion.
SQL is not supposed to be used like this.
In relational databases, a table represents a relation, which is a set by definition. A set contains unordered elements.
Also, don't rely on the physical order of the records. The row order is not guaranteed by the RDBMS.
If the ordering of the records is important, you'd better add a column such as `Num' to the table, and use the following query. This is more natural.
select *
from Table
where Num > N
order by Num

- 793
- 1
- 9
- 17
-
2ANSI SQL: "select * from tablename OFFSET n", and also in this case ORDER BY is recommended. – jarlh Apr 27 '15 at 12:29
-
1(a) Yes, good Answer. See my comment on the Question. (b) In your last sentence, you don't necessaily need to *add* a column, just `ORDER BY …` whatever column is required, to obtain the result you need. (c) Capitalise the `ORDER BY.` – PerformanceDBA Apr 28 '15 at 02:29
Query: in sql-server
DECLARE @N INT = 5 --Any random number
SELECT * FROM (
SELECT ROW_NUMBER() OVER(ORDER BY ID) AS RoNum
, ID --Add any fields needed here (or replace ID by *)
FROM TABLE_NAME
) AS tbl
WHERE @N < RoNum
ORDER BY tbl.ID
This will give rows of Table, where rownumber is starting from @N + 1
.

- 4,920
- 17
- 48
- 72
-
The PRINCIPLE in the answer is OK as such, BUT he made an error and called both his key and counter the same thing..... Change to ".... as RoNu", and "where @N
– Eske Rahn Jun 23 '18 at 15:41 -
(And of course you would normally include more columns than just the ID, simply supplement ID by a field list or replace by an asterisk in the inner select) – Eske Rahn Jun 23 '18 at 15:54
-
I would do `SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0))`. That would completely ignore any order by specific column. – Gabrielius Jul 17 '20 at 15:18
In order to do this in SQL Server, you must order the query by a column, so you can specify the rows you want.
Example:
select * from table order by [some_column]
offset 10 rows
FETCH NEXT 10 rows only

- 4,920
- 17
- 48
- 72

- 494
- 4
- 5
Do you want something like in LINQ skip 5 and take 10?
SELECT TOP(10) * FROM MY_TABLE
WHERE ID not in (SELECT TOP(5) ID From My_TABLE ORDER BY ID)
ORDER BY ID;
This approach will work in any SQL version. You need to stablish some order (by Id for example) so all rows are provided in a predictable manner.

- 2,519
- 23
- 23
-
2This is not a good approach! And anyway without order clause in both parts, you get an unpredictable result: Take 10 random excluding 5 random.... – Eske Rahn Jun 24 '18 at 14:38
-
3The question is not about any particular order. It's about skip first N record from a table. By the way Select doesn't take random, it takes records in the orde were inserted to the table in the first place. – Carlos Toledo Jun 29 '18 at 19:01
-
4It certainly IS about a particular order, as it might not be the ones you got in the first run, that is skipped in the second... There are NO guarantees that you get them in any particular order. Though an SQL COULD be implemented so sequentially added records unaltered would be returned in the same order - but you should not code assuming that.... - but even if an order is added the approach is bad if the number to skip is high – Eske Rahn Jun 29 '18 at 22:49
-
1... on the order part, see e.g. https://dba.stackexchange.com/questions/6051/what-is-the-default-order-of-records-for-a-select-statement-in-mysql – Eske Rahn Jun 29 '18 at 23:00
-
2As others have said, you absolutely need to include ORDER BY here. SELECT does not necessarily produce the records ordered by "where inserted to the table in the first place". – maembe Apr 11 '19 at 19:49
-
All depends. If the Id is a primary key (is a clustered table) rows are inserted following the Id order. Even if you insert record with Id 4 after record with Id 23, the select will show record 4 first. Also the Order By is one of the most expensive operations that we can avoid if the Id is primary key. – Carlos Toledo Jun 15 '19 at 00:07
-
@CarlosToledo A sql statement without `ORDER BY` is not guaranteed to be in any order whatsoever. This answer works on the assumption that `ID` is a single column `PRIMARY KEY` – CervEd Jan 17 '22 at 14:46
I know it's quite late now to answer the query. But I have a little different solution than the others which I believe has better performance because no comparisons are performed in the SQL query only sorting is done. You can see its considerable performance improvement basically when value of SKIP is LARGE enough.
Best performance but only for SQL Server 2012 and above. Originally from @Majid Basirati's answer which is worth mentioning again.
DECLARE @Skip INT = 2, @Take INT = 2 SELECT * FROM TABLE_NAME ORDER BY ID ASC OFFSET (@Skip) ROWS FETCH NEXT (@Take) ROWS ONLY
Not as Good as the first one but compatible with SQL Server 2005 and above.
DECLARE @Skip INT = 2, @Take INT = 2 SELECT * FROM ( SELECT TOP (@Take) * FROM ( SELECT TOP (@Take + @Skip) * FROM TABLE_NAME ORDER BY ID ASC ) T1 ORDER BY ID DESC ) T2 ORDER BY ID ASC

- 1,494
- 1
- 13
- 21
-
Actually the ROW_NUMBER(...) approach gives a MUCH better performance than the OFFSET approach, if the offset is not very small (less than about 30). But the Offset have the in some scenarios great ability that it is a pure append to an existing ordered select.(perhaps generated dynamical by something out of our control) – Eske Rahn Jun 28 '18 at 15:13
-
I just ran some tests with a complex record set of 10,000,000 records joined across 3 tables with a date sort dependency, and it's true, when the offset hits the 6,000,000 mark, the ROW_NUMBER approach is faster, but only nominally so - about 25% faster. Interestingly, at lower offsets, the OFFSET approach was considerably faster. I think this is due to the complex nature of the data set joins and sort that I have to do. Regardless, thanks for both of these approaches. I think I'll stick to the OFFSET() approach from now on unless I hit measurable performance issues. – Pete Magsig Feb 25 '21 at 20:13
-
6Note that this will not work in all flavors of SQL, as the `LIMIT` and `OFFSET` keywords are not part of the ANSI standard (see [this question](http://stackoverflow.com/q/1528604/168775)). – eykanal Jan 28 '16 at 21:42
-
first should be OFFSET keyword and then the LIMIT keyword: `SELECT * FROM table OFFSET 1 LIMIT 50` – kederrac Apr 01 '21 at 12:46
This works with all DBRM/SQL, it is standard ANSI:
SELECT *
FROM owner.tablename A
WHERE condition
AND n+1 <= (
SELECT COUNT(DISTINCT b.column_order)
FROM owner.tablename B
WHERE condition
AND b.column_order>a.column_order
)
ORDER BY a.column_order DESC

- 11
- 1
-
The coded select statement above skip the first n rows with bigger value in column_order. You can change condition to retrieve smaller, as you want. – fspino Apr 21 '17 at 12:07
PostgreSQL: OFFSET
without LIMIT
This syntax is supported, and it is in my opinion the cleanest API compared to other SQL implementations as it does not introduce any new keywords:
SELECT * FROM mytable ORDER BY mycol ASC OFFSET 1
that should definitely be standardized.
The fact that this is allowed can be seen from: https://www.postgresql.org/docs/13/sql-select.html since LIMIT
and OFFSET
can be given independently, since OFFSET
is not a sub-clause of LIMIT
in the syntax specification:
[ LIMIT { count | ALL } ]
[ OFFSET start [ ROW | ROWS ] ]
SQLite: negative limit
OFFSET
requires LIMIT
in that DBMS, but dummy negative values mean no limit. Not as nice as PostgreSQL, but it works:
SELECT * FROM mytable ORDER BY mycol ASC LIMIT -1 OFFSET 1
Asked at: SQLite with skip (offset) only (not limit)
Documented at: https://sqlite.org/lang_select.html
If the LIMIT expression evaluates to a negative value, then there is no upper bound on the number of rows returned.
MySQL: use a huge limit number
Terrible API design, the documentation actually recommends it:
SELECT * FROM tbl LIMIT 1,18446744073709551615;
Asked at: MySQL skip first 10 results
Node.js Sequelize ORM implements it
That ORM allows e.g. findAll({offset:
without limit:
, and implements workarounds such as the ones mentioned above for each different DBMS.

- 347,512
- 102
- 1,199
- 985
In Faircom SQL (which is a pseudo MySQL), i can do this in a super simple SQL Statement, just as follows:
SELECT SKIP 10 * FROM TABLE ORDER BY Id
Obviously you can just replace 10
with any declared variable of your desire.
I don't have access to MS SQL or other platforms, but I'll be really surprised MS SQL doesn't support something like this.

- 199
- 1
- 7
DECLARE @Skip int= 2, @Take int= 2
SELECT * FROM TABLE_NAME
ORDER BY Column_Name
OFFSET (@Skip) ROWS FETCH NEXT (@Take) ROWS ONLY

- 5,451
- 11
- 25
- 47
try below query it's work
SELECT * FROM `my_table` WHERE id != (SELECT id From my_table LIMIT 1)
Hope this will help

- 2,113
- 3
- 20
- 28
You can also use OFFSET to remove the 1st record from your query result like this-
Example - find the second max salary from the employee table
select distinct salary from employee order by salary desc limit 1 OFFSET 1

- 171
- 2
- 9
For SQL Server 2012 and later versions, the best method is @MajidBasirati's answer.
I also loved @CarlosToledo's answer, it's not limited to any SQL Server version but it's missing Order By Clauses. Without them, it may return wrong results.
For SQL Server 2008 and later I would use Common Table Expressions for better performance.
-- This example omits first 10 records and select next 5 records
;WITH MyCTE(Id) as
(
SELECT TOP (10) Id
FROM MY_TABLE
ORDER BY Id
)
SELECT TOP (5) *
FROM MY_TABLE
INNER JOIN MyCTE ON (MyCTE.Id <> MY_TABLE.Id)
ORDER BY Id

- 49
- 11