Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Oracle rownum returning wrong result

Tags:

sql

oracle

I am trying a query to return only the latest row from table.

Initially I used max(id) in query But as I use sequence and my envoirnment is clustered, I cannot rely on sequence as its out of order. So I decided to order based on creation time and pick top row using rownum.

I used something like

SELECT  A.id
    FROM Table_A, Table_B B
    WHERE A.status = 'COMPLETED'
    AND B.name = 'some_name'
    AND A.id = B.id
    AND rownum = 1
    order by A.Creation_Time;

This some how returns me some wrong result say 42145. If I remove the rownum condtn the top record is differnet say 45343;

like image 253
Aditya Avatar asked Jan 22 '15 17:01

Aditya


People also ask

Why Rownum 2 is not valid in Oracle?

Oracle's ROWNUM starts on 1 and is only incremented when assigned to a row that passes the WHERE condition. Since you're filtering on ROWNUM=2, ROWNUM=1 doesn't pass the WHERE condition, and ROWNUM is therefore never assigned to a row and incremented to 2.

What is the difference between Rownum and ROW_NUMBER in Oracle?

From a little reading, ROWNUM is a value automatically assigned by Oracle to a rowset (prior to ORDER BY being evaluated, so don't ever ORDER BY ROWNUM or use a WHERE ROWNUM < 10 with an ORDER BY ). ROW_NUMBER() appears to be a function for assigning row numbers to a result set returned by a subquery or partition.

How does Oracle assign Rownum?

You can use ROWNUM to limit the number of rows returned by a query, as in this example: SELECT * FROM employees WHERE ROWNUM < 10; If an ORDER BY clause follows ROWNUM in the same query, then the rows will be reordered by the ORDER BY clause. The results can vary depending on the way the rows are accessed.

Is Rownum unique in Oracle?

ROW_NUMBER is an analytic function. It assigns a unique number to each row to which it is applied (either each row in the partition or each row returned by the query), in the ordered sequence of rows specified in the order_by_clause , beginning with 1.


1 Answers

When using rownum with order by, you need to use a subquery. This has to do with the order of evaluation of the where and order by. So, try this:

SELECT t.*
FROM (SELECT A.id
      FROM Table_A JOIN 
           Table_B B
           ON A.id = B.id
      WHERE A.status = 'COMPLETED' AND B.name = 'some_name'
      ORDER BY A.Creation_Time
     ) ab
WHERE rownum = 1;

I should add: Oracle 12 supports fetch first 1 row only, which is more convenient:

  SELECT A.id
  FROM Table_A JOIN 
       Table_B B
       ON A.id = B.id
  WHERE A.status = 'COMPLETED' AND B.name = 'some_name'
  ORDER BY A.Creation_Time
  FETCH FIRST 1 ROW ONLY;
like image 113
Gordon Linoff Avatar answered Oct 18 '22 16:10

Gordon Linoff