简体   繁体   English

Oracle SQL查询行数不一致

[英]Oracle SQL Query rownum inconsistent

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 返回3行

1: (null)
2: Expected Outcome
3: Some other previous outcome

Added ROWNUM=2 , which is the row I want. 添加了ROWNUM=2 ,这是我想要的行。

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 结果为1: (null)而不是预期的1: Expected Outcome

If I try with ROWNUM=1 I receive, what I'd expect in that instance which is 1: (null) 如果我尝试使用ROWNUM=1收到,那么在该实例中的期望值为1: (null)

How can I retrieve that middle row consistently? 如何连续检索中间行?

A query with WHERE ROWNUM = X or WHERE ROWNUM > X doesn't make sense. WHERE ROWNUM = XWHERE ROWNUM > X的查询没有意义。 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. 这是因为ROWNUM值在谓词求值期间分配给行,并且仅在行通过WHERE子句后才递增。

source 资源

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. 实际上,上述解决方案是错误的,因为ROWNUM将在ORDER BY子句之前分配。 Without using ROW_NUMBER() (like in zaratustra's answer ), the right solution is: 不使用ROW_NUMBER() (如zaratustra的answer一样 ),正确的解决方案是:

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: ROWNUM在您的情况下是不可预测的,在rownum = n (n > 1)rownum > nn是任何自然数)的情况下是不可访问的,您必须像这样使用ROW_NUMBER()

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 = 2 (或ROWNUM > 1 )将始终导致找不到行。 ROWNUM is generated as rows are output from the query, after all conditions are evaluated ; 在评估所有条件之后,将生成ROWNUM, 作为查询的行输出 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 . 因此,查询的第一行输出被分配为ROWNUM 1,下一行被分配为ROWNUM 2,依此类推。因此,要求获得ROWNUM = 2的行等同于要求get me the second row emitted from the query中不会发生get me the second row emitted from the query ,因为ROWNUM = 2比较意味着查询将永远不会出现第一行,该行将具有ROWNUM = 1

Thus, I believe that the only workable comparisons on ROWNUM are: 因此,我相信ROWNUM上唯一可行的比较是:

= 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. 在这里,我们在内部查询中创建一个名为RNUM的临时列,为它分配内部查询生成的ROWNUM的值。 In the outer query we test RNUM to see if it's equal to 2. 在外部查询中,我们测试RNUM是否等于2。

Share and enjoy. 分享并享受。

Row numbers are assigned at the runtime and you can fetch a particular row by matching the rownum. 行号是在运行时分配的,您可以通过匹配rownum来获取特定行。 You can achieve this by including the rownum in your sub-query. 您可以通过在子查询中包含rownum来实现此目的。 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM