ROWNUM is a magic column in Oracle Database that gets many people into trouble. When you learn what it is and how it works, however, it can be very useful. I use it for two main things:
To perform top- N processing. This is similar to using the LIMIT clause, available in some other databases.
To paginate through a query, typically in a stateless environment such as the Web. We can use this.
How ROWNUM Works?
ROWNUM is a pseudocolumn (not a real column) that is available in a query. ROWNUM will be assigned the numbers 1, 2, 3, 4, … N , where N is the number of rows in the set ROWNUM is used with. A ROWNUM value is not assigned permanently to a row (this is a common misconception). A row in a table does not have a number; you cannot ask for row 5 from a table—there is no such thing.
Also confusing to many people is when a ROWNUM value is actually assigned. A ROWNUM value is assigned to a row after it passes the predicate phase of the query but before the query does any sorting or aggregation. Also, a ROWNUM value is incremented only after it is assigned, which is why the following query will never return a row:
WHEREROWNUM > 1;
Because ROWNUM > 1 is not true for the first row, ROWNUM does not advance to 2. Hence, no ROWNUM value ever gets to be greater than 1. Consider a query with this structure:
SELECT ..., ROWNUMFROM T
WHERE <WHERE CLAUSE>
HAVING <HAVING CLAUSE>
Think of it as being processed in this order:
The FROM/WHERE clause goes first.
ROWNUM is assigned and incremented to each output row from the FROM/WHERE clause.
SELECT is applied.
GROUP BY is applied.
HAVING is applied.
ORDER BY is applied.
That is why a query in the following form is almost certainly an error:
WHEREROWNUM <= 5ORDERBY sal DESC;
The intention was most likely to get the five highest-paid people—a top- N query. What the query will return is five random records (the first five the query happens to hit), sorted by salary. The procedural pseudocode for this query is as follows:
ROWNUM = 1
FOR x in
(SELECT * FROM emp)
LOOPexitwhenNOT(ROWNUM <= 5)
ROWNUM = ROWNUM+1endloopSORT TEMP
It gets the first five records and then sorts them. A query with WHERE ROWNUM = 5 or WHERE ROWNUM > 5 doesn’t make sense. This is because a ROWNUM value is assigned to a row during the predicate evaluation and gets incremented only after a row passes the WHERE clause.
Here is the correct version of this query:
FROM (SELECT *
ORDERBY sal DESC)
WHEREROWNUM <= 5;
This version will sort EMP by salary descending and then return the first five records it encounters (the top-five records). As you’ll see in the top- N discussion coming up shortly, Oracle Database doesn’t really sort the entire result set—it is smarter than that—but conceptually that is what takes place.
For pagination, if you want the 5 -10 records of the employee order by hiredate asc then go for this.
FROM (SELECTROWNUM rn, inner.*
FROM ( SELECT e.*
FROM employee e
ORDERBY hiredate) inner) outerWHERE outer.rn >= 5AND outer.rn <= 10