Assuming that you are trying to generate pages of data and assuming that your desire is that the results are stable and consistent if the data in the table isn't changing (every row from the inner query is returned on exactly one page of the results as you vary the upper and lower bounds), the most efficient approach would be essentially what you posted initially. But you do need to add an ORDER BY
to the inner query. Otherwise, it would be perfectly correct for Oracle to return one row of data on every page or to never return a row on any page
SELECT orderid
FROM (SELECT orderid, rownum r
FROM (SELECT orderid
FROM myorders
WHERE ordertype = 'E'
AND orderstatus = 'A'
ORDER BY <<something>>) a
WHERE rownum < 86)
WHERE r > 84
If you are really more concerned about readability than performance, you can reduce that by one level of nesting by doing something like
SELECT orderid
FROM (SELECT orderid,
rank() over (order by <<something>>) rnk
FROM myorders
WHERE ordertype = 'E'
AND orderstatus = 'A')
WHERE rnk > 84
AND rnk < 86
In Oracle 12c, Oracle is expected to support the ANSI FETCH
and OFFSET
keywords to simplify the syntax a bit further.