The below queries results seem inconsistent to me.
select OUTCOME from (select OUTCOME, NUMBER1
from TASK
order by TASK_NUMBER desc)
where NUMBER1 = 1500
Returns 3 rows
1: (null)
2: Expected Outcome
3: Some other previous outcome
Added ROWNUM=2
, which is the row I want.
select OUTCOME from (select OUTCOME, NUMBER1
from TASK
order by TASK_NUMBER desc)
where NUMBER1 = 1500 and
ROWNUM=2
Result is 1: (null)
rather than the expected 1: Expected Outcome
If I try with ROWNUM=1
I receive, what I'd expect in that instance which is 1: (null)
How can I retrieve that middle row consistently?
A query with
WHERE ROWNUM = X
orWHERE ROWNUM > X
doesn't make sense. This is because aROWNUM
value is assigned to a row during the predicate evaluation and gets incremented only after a row passes theWHERE
clause.
select OUTCOME from
(select OUTCOME, NUMBER1, ROWNUM RN from TASK order by TASK_NUMBER desc)
where NUMBER1 = 1500 and RN=2
EDIT
Actually, above solution is false, because ROWNUM
will be assigned before ORDER BY
clause. Without using ROW_NUMBER()
(like in zaratustra's answer ), the right solution is:
select OUTCOME from (
select ROWNUM RN, OUTCOME, NUMBER1
from (select OUTCOME, NUMBER1 from TASK order by TASK_NUMBER desc)
) where NUMBER1 = 1500 and RN=2
ROWNUM is unpredictable in your case and unreachable for cases rownum = n (n > 1)
or rownum > n
( n
is any natural number), you have to use ROW_NUMBER()
like this:
select OUTCOME
from (
select OUTCOME
, NUMBER1
, ROW_NUMBER() OVER(order by TASK_NUMBER desc) rn
from TASK
)
where NUMBER1 = 1500
and rn=2
ROWNUM = 2
(or ROWNUM > 1
) will always cause no rows to be found. ROWNUM is generated as rows are output from the query, after all conditions are evaluated ; thus, the first row output from the query is assigned ROWNUM 1, the next gets ROWNUM 2, etc. Thus, asking for the row where ROWNUM = 2
is equivalent to asking get me the second row emitted from the query
which will never occur, because the ROWNUM = 2
comparison means there will never be a first row emitted from the query, which would have ROWNUM = 1
.
Thus, I believe that the only workable comparisons on ROWNUM are:
= 1
>= 1
< n
BETWEEN 1 and n
One way to work around this is to rewrite your query as:
select OUTCOME from (select OUTCOME, NUMBER1, ROWNUM as RNUM
from TASK
order by TASK_NUMBER desc)
where NUMBER1 = 1500 and
RNUM = 2
Here we create a temp column named RNUM in the inner query, assigning it the value of ROWNUM as generated by the inner query. In the outer query we test RNUM to see if it's equal to 2.
Share and enjoy.
Row numbers are assigned at the runtime and you can fetch a particular row by matching the rownum. You can achieve this by including the rownum in your sub-query. Please use the query below:
select OUTCOME from (select OUTCOME, NUMBER1,ROWNUM RID from TASK order by TASK_NUMBER desc) where NUMBER1 = 1500 and RID=2
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.