Oracle Database has a FETCH
clause that allows us to limit the number of rows returned by a SELECT
statement.
We can use this clause to specify the exact number of rows or the percentage of rows that a query should return. We can also specify an offset for which to start.
Syntax
The syntax goes like this:
[ OFFSET offset { ROW | ROWS } ]
[ FETCH { FIRST | NEXT } [ { rowcount | percent PERCENT } ]
{ ROW | ROWS } { ONLY | WITH TIES } ]
So we have quite a few options with how we construct our FETCH
clauses. The following examples demonstrate the various options.
The ROW
and ROWS
keywords mean the same thing. Both keywords are provided for semantic clarity and can be used interchangeably.
The same applies to the FIRST
and NEXT
keywords.
Sample Data
Suppose we have a table with the following data:
SELECT
ProductId,
ProductName,
ProductPrice
FROM Products
ORDER BY ProductId;
Result:
PRODUCTID | PRODUCTNAME | PRODUCTPRICE |
---|---|---|
1 | Left handed screwdriver | 25.99 |
2 | Right handed screwdriver | 25.99 |
3 | Long Weight (blue) | 14.75 |
4 | Long Weight (green) | 11.99 |
5 | Sledge Hammer | 33.49 |
6 | Chainsaw | 245 |
7 | Straw Dog Box | 55.99 |
8 | Hammock | 10 |
9 | Bottomless Coffee Mugs (4 Pack) | 9.99 |
10 | Tea Pot | 12.45 |
We can see that the table contains ten rows of data.
Basic Example of the FETCH
Clause
Here’s an example of adding the FETCH
clause to the above query in order to limit the number of rows returned:
SELECT
ProductId,
ProductName,
ProductPrice
FROM Products
ORDER BY ProductId
FETCH FIRST 3 ROWS ONLY;
Result:
PRODUCTID | PRODUCTNAME | PRODUCTPRICE |
---|---|---|
1 | Left handed screwdriver | 25.99 |
2 | Right handed screwdriver | 25.99 |
3 | Long Weight (blue) | 14.75 |
In this case I limited the results to just the first three rows.
As previously mentioned, ROW
and ROWS
can be used interchangeably. So I could have used 3 ROW
but it makes more semantic sense to use ROWS
plural. If I was only returning one row, I could use FIRST 1 ROW
, which would make better semantic sense, but I could equally use FIRST 1 ROWS
.
The same applies to the FIRST
and NEXT
keywords. I could replace FIRST
with NEXT
and get the same result.
So I could get the same result by changing the whole thing to the following:
SELECT
ProductId,
ProductName,
ProductPrice
FROM Products
ORDER BY ProductId
FETCH NEXT 3 ROW ONLY;
Result:
PRODUCTID | PRODUCTNAME | PRODUCTPRICE |
---|---|---|
1 | Left handed screwdriver | 25.99 |
2 | Right handed screwdriver | 25.99 |
3 | Long Weight (blue) | 14.75 |
Sorting
The above examples are sorted by the ProductId
column. Specifying a different order can change the result:
SELECT
ProductId,
ProductName,
ProductPrice
FROM Products
ORDER BY ProductPrice
FETCH FIRST 3 ROWS ONLY;
Result:
PRODUCTID | PRODUCTNAME | PRODUCTPRICE |
---|---|---|
9 | Bottomless Coffee Mugs (4 Pack) | 9.99 |
8 | Hammock | 10 |
4 | Long Weight (green) | 11.99 |
Here, the FETCH
clause itself is no different than in the previous example. But I changed the order of the results by passing a different column name to the ORDER BY
clause. This changed the end result. We still got three rows, but it was a different set of rows. This is because the first three rows are different when sorted by the different column.
Ties
In the previous examples I used the ONLY
keyword. When we use the ONLY
keyword, the query returns the exact number of rows that we specified, even if there are ties. A tie is when two or more rows contain the same value in the column that we sorted the results by.
We can use WITH TIES
instead of ONLY
to specify that any ties are included in the result, even if it means exceeding the limit count that we specify.
Here’s an example to demonstrate what I mean:
SELECT
ProductId,
ProductName,
ProductPrice
FROM Products
ORDER BY ProductPrice DESC
FETCH FIRST 4 ROWS WITH TIES;
Result:
PRODUCTID | PRODUCTNAME | PRODUCTPRICE |
---|---|---|
6 | Chainsaw | 245 |
7 | Straw Dog Box | 55.99 |
5 | Sledge Hammer | 33.49 |
1 | Left handed screwdriver | 25.99 |
2 | Right handed screwdriver | 25.99 |
Five rows are returned instead of the four that we specified. That’s because we got a tie for fourth place.
In this case I sorted by the ProductPrice
column and specified a row limit of 4
. As it turns out, two rows contain the same value in their ProductPrice
column, which means they both tie for fourth place. The WITH TIES
keyword resulted in both of them being returned.
Now, here’s what happens when we replace WITH TIES
with ONLY
:
SELECT
ProductId,
ProductName,
ProductPrice
FROM Products
ORDER BY ProductPrice DESC
FETCH FIRST 4 ROWS ONLY;
Result:
PRODUCTID | PRODUCTNAME | PRODUCTPRICE |
---|---|---|
6 | Chainsaw | 245 |
7 | Straw Dog Box | 55.99 |
5 | Sledge Hammer | 33.49 |
1 | Left handed screwdriver | 25.99 |
This time, only four rows are returned. Only one of the tied rows is returned.
Specifying a Percentage
We can use the PERCENT
keyword to specify a percentage of rows to return instead of an absolute number:
SELECT
ProductId,
ProductName,
ProductPrice
FROM Products
ORDER BY ProductId
FETCH FIRST 30 PERCENT ROWS ONLY;
Result:
PRODUCTID | PRODUCTNAME | PRODUCTPRICE |
---|---|---|
1 | Left handed screwdriver | 25.99 |
2 | Right handed screwdriver | 25.99 |
3 | Long Weight (blue) | 14.75 |
In this case, I specified 30 percent as the number of rows to return. The table contains ten rows, and so 30 percent of ten is 3.
Adding an Offset
We can combine the FETCH
clause with the OFFSET
clause to specify an offset:
SELECT
ProductId,
ProductName,
ProductPrice
FROM Products
ORDER BY ProductId
OFFSET 1 ROW FETCH NEXT 3 ROWS ONLY;
Result:
PRODUCTID | PRODUCTNAME | PRODUCTPRICE |
---|---|---|
2 | Right handed screwdriver | 25.99 |
3 | Long Weight (blue) | 14.75 |
4 | Long Weight (green) | 11.99 |
Here, I used the OFFSET
clause to offset the rows by 1. This caused the result set to start at the second row.