fetching data using rownum in oracle - sql

I have a query in oracle to fetch data from table using rownum but i didn't get any data.
My query is like this :
select * from table-name where rownum<5
is this is a wrong query to fetch data whose row number is less than 5.
when i used query like :
select * from table-name where rownum<=4
than it will gives a result record.
My question is what is wrong here with ?
Is this is syntax error or anything else??..

rownum is a pseudo column that counts rows in the result set after the where clause has been applied.
SELECT table_name
FROM user_tables
WHERE rownum > 2;
TABLE_NAME
------------------------------
0 rows selected
However, this query will always return zero rows, regardless of the number of rows in the table.
To explain this behaviour, we need to understand how Oracle processes ROWNUM. When assigning ROWNUM to a row, Oracle starts at 1 and only increments the value when a row is selected; that is, when all conditions in the WHERE clause are met. Since our condition requires that ROWNUM is greater than 2, no rows are selected and ROWNUM is never incremented beyond 1.
http://blog.lishman.com/2008/03/rownum.html
another stackoverflow link
Edited
this paragraph i find on oracle website which is much better
Conditions testing for ROWNUM values greater than a positive integer are always false. For example, this query returns no rows:
SELECT * FROM employees
WHERE ROWNUM > 1;
The first row fetched is assigned a ROWNUM of 1 and makes the condition false. The second row to be fetched is now the first row and is also assigned a ROWNUM of 1 and makes the condition false. All rows subsequently fail to satisfy the condition, so no rows are returned.
You can also use ROWNUM to assign unique values to each row of a table, as in this example:

Syntax seems correct to me.
However ROWNUM is calculated on result rows for example:
SELECT * FROM TABLE_NAME WHERE ROWNUM < 10 ORDER BY TABLE_FIELD ASC;
and
SELECT * FROM TABLE_NAME WHERE ROWNUM < 10 ORDER BY TABLE_FIELD DESC;
Will give you different results.
Each time a query is executed, for each tuple, Oracle assigns a ROWNUM which is scopet to that only query.
What are you trying to accomplish ?

Since for the reasons rahularyansharma mentions, rownum based queries won't always function the way you might expect, a way around this is to do something like
SELECT * from (SELECT rownum AS rn, TABLE_NAME.* FROM TABLE_NAME)
where rn > 5;
However, be aware that this will be a fairly inefficient operation when operating over large datasets.

Related

How to select only 10 records from the table in jsp?

I'm try to select only 10 row from a table by using limit but it gives me an error,
My query is
SELECT *
FROM table_name
ORDER BY CUSTOMER
LIMIT 10
It gives an error :
ORA-00933: SQL command not properly ended
Can anyone guide me.
You can use ROWNUM :
SELECT *
FROM ( SELECT *
FROM table_name
ORDER BY CUSTOMER) t
WHERE ROWNUM <=10
For each row returned by a query, the ROWNUM pseudocolumn returns a number indicating the order in which Oracle selects the row from a table or set of joined rows. The first row selected has a ROWNUM of 1, the second has 2, and so on.
Or, since Oracle 12c r1, you can use FETCH :
SELECT *
FROM table_name
ORDER BY CUSTOMER
FETCH FIRST 10 ROWS ONLY
FETCH
Use this clause to specify the number of rows or percentage of rows to return. If you do not specify this clause, then all rows are returned, beginning at row offset + 1.
FIRST | NEXT
These keywords can be used interchangeably and are provided for semantic clarity.

Oracle Row fetch within limit

I want to fetch data between 10000 to 20000 rownum i have made this query
SELECT xml_to_string(XMLRECORD) FROM TABLENAME WHERE ROWNUM >10000 AND ROWNUM<=20000
but above query is not working but when i change query to
SELECT xml_to_string(XMLRECORD) FROM TABLENAME WHERE ROWNUM >0 AND ROWNUM<=20000
it works fine
what am i missing..?
Try this:
SELECT xml_to_string(XMLRECORD) FROM (select t.*, rownum rw from TABLENAME t)
WHERE rw>10000 AND rw<=20000
Rownum is calculated when Oracle retrieves the result of the query. That's why a query select * from some_table where rownum > 1 never returns anything.
In addition, without ORDER BY it doesn't make sense to get rows between 10000 and 20000. You might as well get the first 10000 (as rows are unsorted the result is unpredictable - any row can be the first).
From Oracle documentation:
For each row returned by a query, the ROWNUM pseudocolumn returns a
number indicating the order in which Oracle selects the row from a
table or set of joined rows. The first row selected has a ROWNUM of 1,
the second has 2, and so on.
Conditions testing for ROWNUM values greater than a positive integer
are always false. For example, this query returns no rows:
SELECT *
FROM employees
WHERE ROWNUM > 1;
The first row fetched is assigned a ROWNUM of 1 and makes the
condition false. The second row to be fetched is now the first row and
is also assigned a ROWNUM of 1 and makes the condition false. All rows
subsequently fail to satisfy the condition, so no rows are returned.
rownum doesnot stay in any table It generates run time so when ever you run any sql statement then only for that time rownum will generate so you can't expect that you can use row num in between close.

Why = operator doesn't work with ROWNUM other than for value 1?

I have the following query:
select * from abc where rownum = 10
Output: No records to display
I sure have more than 25 records in the abc table and my objective is to display the nth record.
If I write the query as: -
select * from abc where rownum = 1
it works fine and gives me the first record. Not any other record other than first.
Any idea?
Because row numbers are assigned sequentially to the rows that are fetched and returned.
Here's how that statement of yours works. It grabs the first candidate row and temporarily gives it row number 1, which doesn't match your condition so it's thrown away.
Then you get the second candidate row and it's also given row number 1 (since the previous one was tossed away). It doesn't match either.
Then the third candidate row ... well, I'm sure you can see where this is going now. In short, you will never find a row that satisfies that condition.
Row numbers are only useful for = 1, < something or <= something.
This is all explained in the Oracle docs for the rownum pseudo-column.
You should also keep in mind that SQL is a relational algebra that returns unordered sets unless you specify an order. That means row number ten may be something now and something else in three minutes.
If you want a (kludgy, admittedly) way to get the nth row, you can use something like (for the fifth row):
select * from (
select * from (
select col1, col2, col3 from tbl order by col1 asc
) where rownum < 6 order by col1 desc
) where rownum = 1
The inner select will ensure you have a consistent order on the query before you start throwing away rows, and the middle select will throw away all but the first five rows from that, and also reverse the order.
The outer select will then only return the first row of the reversed set (which is the last row of the five-row set when it was in ascending order).
A better way is probably:
select * from (
select rownum rn, col1, col2, col3 from tbl order by col1
) where rn = 5
This works by retrieving everything and assigning the rownum to a "real" column, then using that real column number to filter the results.

Clarification on "rownum"

I have a table Table1
Name Date
A 01-jun-2010
B 03-dec-2010
C 12-may-2010
When i query this table with the following query
select * from table1 where rownum=1
i got output as
Name Date
A 01-jun-2010
But in the same way when i use the following queries i do not get any output.
select * from table1 where rownum=2
select * from table1 where rownum=3
Someone please give me guidance why it works like that, and how to use the rownum.
Tom has an answer for many Oracle related questions
In short, rownum is available after the where clause has been applied and before the order by clause is applied.
In the case of RowNum=2, the predicate in the where clause will never evaluate to true as RowNum starts at 1 and only increases if records matching the predicate can be found.
Adding rownums is one of the last things done after the result set has been fetched from the database. This means that the first row will always have rownum 1. Rownum is better used when you want to limit the result set, for instance when doing paging.
See this for more: http://www.orafaq.com/wiki/ROWNUM
(Not an Oracle expert by any means)
From what I understand, rownum numbers the rows in a result set.
So, in your example:
select * from table1 where rownum=2
How many rows are there going to be in the result set? Therefore, what rownum would be assigned to such a row? Can you see now why no result is actually returned?
In general, you should avoid relying on rownum, or any features that imply an order to results. Try to think about working with the entire set of results.
With that being said, I believe the following would work:
select * from (select rownum as rn,table1.* from table1) as t where t.rn = 2
Because in that case, you're numbering the rows within the subquery.

Paging with Oracle and sql server and generic paging method

I want to implement paging in a gridview or in an html table which I will fill using ajax. How should I write queries to support paging? For example if pagesize is 20 and when the user clicks page 3, rows between 41 and 60 must be shown on table. At first I can get all records and put them into cache but I think this is the wrong way. Because data can be very huge and data can be change from other sessions. so how can I implement this? Is there any generic way ( for all databases ) ?
As others have suggested, you can use rownum in Oracle. It's a little tricky though and you have to nest your query twice.
For example, to paginate the query
select first_name from some_table order by first_name
you need to nest it like this
select first_name from
(select rownum as rn, first_name from
(select first_name from some_table order by first_name)
) where rn > 100 and rn <= 200
The reason for this is that rownum is determined after the where clause and before the order by clause. To see what I mean, you can query
select rownum,first_name from some_table order by first_name
and you might get
4 Diane
2 Norm
3 Sam
1 Woody
That's because oracle evaluates the where clause (none in this case), then assigns rownums, then sorts the results by first_name. You have to nest the query so it uses the rownum assigned after the rows have been sorted.
The second nesting has to do with how rownum is treated in a where condition. Basically, if you query "where rownum > 100" then you get no results. It's a chicken and egg thing where it can't return any rows until it finds rownum > 100, but since it's not returning any rows it never increments rownum, so it never counts to 100. Ugh. The second level of nesting solves this. Note it must alias the rownum column at this point.
Lastly, your order by clause must make the query deterministic. For example, if you have John Doe and John Smith, and you order by first name only, then the two can switch places from one execution of the query to the next.
There are articles here http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html
and here http://www.oracle.com/technology/oramag/oracle/07-jan/o17asktom.html. Now that I see how long my post is, I probably should have just posted those links...
Unfortunately, the methods for restricting the range of rows returned by a query vary from one DBMS to another: Oracle uses ROWNUM (see ocdecio's answer), but ROWNUM won't work in SQL Server.
Perhaps you can encapsulate these differences with a function that takes a given SQL statement and first and last row numbers and generates the appropriate paginatd SQL for the target DBMS - i.e. something like:
sql = paginated ('select empno, ename from emp where job = ?', 101, 150)
which would return
'select * from (select v.*, ROWNUM rn from ('
+ theSql
+ ') v where rownum < 150) where rn >= 101'
for Oracle and something else for SQL Server.
However, note that the Oracle solution is adding a new column RN to the results that you'll need to deal with.
I believe that both have a ROWNUM analytic Function. Use that and you'll be identical.
In Oracle it is here
ROW_NUMBER
Yep, just verified that ROW_NUMBER is the same function in both.
"Because...data can be change from other sessions."
What do you want to happen for this ?
For example, user gets the 'latest' ten rows at 10:30.
At 10:31, 3 new rows are added (so those ten being view by the user are no longer the latest).
At 10:32, the user requests then 'next' ten entries.
Do you want that new set to include those three that have been bumped from 8/9/10 down to 11/12/13 ?
If not, in Oracle you can select the data as it was at 10:30
SELECT * FROM table_1 as of timestamp (timestamp '2009-01-29 10:30:00');
You still need the row_number logic, eg
select * from
(SELECT a.*, row_number() over (order by hire_date) rn
FROM hr.employees as of timestamp (timestamp '2009-01-29 10:30:00') a)
where rn between 10 and 19
select *
from ( select /*+ FIRST_ROWS(n) */ a.*,
ROWNUM rnum
from ( your_query_goes_here,
with order by ) a
where ROWNUM <=
:MAX_ROW_TO_FETCH )
where rnum >= :MIN_ROW_TO_FETCH;
Step 1: your query with order by
Step 2: select a.*, ROWNUM rnum from ()a where ROWNUM <=:MAX_ROW_TO_FETCH
Step 3: select * from ( ) where rnum >= :MIN_ROW_TO_FETCH;
put 1 in 2 and 2 in 3
If the expected data set is huge, I'd recommend to create a temp table, a view or a snapshot (materialized view) to store the query results + a row number retrieved either using ROWNUM or ROW_NUMBER analytic function. After that you can simply query this temp storage using row number ranges.
Basically, you need to separate the actual data fetch from the paging.
There is no uniform way to ensure paging across various RDBMS products. Oracle gives you rownum which you can use in where clause like:
where rownum < 1000
SQL Server gives you row_id( ) function which can be used similar to Oracle's rownum. However, row_id( ) isn't available before SQL Server 2005.