繁体   English   中英

oracle sql wih rownum <=

[英]oracle sql wih rownum <=

如果我从查询中删除<符号,为什么下面的查询没有给出结果。即使没有<它也必须与结果匹配?

用于获取第二个最大id值的查询:

select min(id) 
from(
    select distinct id 
    from student 
    order by id desc
) 
where rownum <=2


student id 
1
2
3
4

Rownum在Oracle中具有特殊含义。 它随着每一行的增加而增加,但是优化器知道它在不断增加,并且所有连续的行都必须满足rownum条件。 因此,如果您指定rownum = 2 ,则由于第一行已被拒绝,因此它将永远不会发生。

如果您对查询做一个解释计划,您会发现这很好。 它将显示如下内容:

计划rownum <=

COUNT STOPKEY       

计划rownum =

FILTER

ROWNUM值不会永久分配给行(这是常见的误解)。 表格中的行没有数字; 您无法从表格中询问第2行或第3行,请点击此处获取更多信息。

这来自提供的链接:

当实际分配了ROWNUM值时,许多人也感到困惑。 ROWNUM值在经过查询的谓词阶段之后但在查询进行任何排序或聚合之前被分配给一行。 另外,仅在分配ROWNUM值后才递增它,这就是为什么以下查询永远不会返回行的原因:

select * 
 from t 
 where ROWNUM > 1;

因为第一行的ROWNUM> 1不正确,所以ROWNUM不会前进到2。因此,任何ROWNUM值都不会大于1。考虑具有以下结构的查询:

select ..., ROWNUM
from t
where <where clause>
group by <columns>
having <having clause>
order by <columns>;

我认为这是您要查找的查询:

select id
from (select distinct id
      from student
      order by id desc
     ) t
where rownum <= 2;

Oracle在order by之前处理rownum ,因此您需要一个子查询来获取前两行。 min()强制执行仅返回一个结果但在应用rownum之前的聚合。

如果实际上只需要第二个值,则需要一个附加的子查询层:

select min(id)
from (select id
      from (select distinct id
            from student
            order by id desc
           ) t
      where rownum <= 2
     ) t;

但是,我会这样做:

select id
from (select id, dense_rank() over (order by id) as seqnum
      from student
     ) t
where seqnum = 2;

为什么不只是使用

select  id
from    ( select distinct id
          ,      row_number() over (order by id desc) x
          from   student
        )
where   x = 2

甚至真的很糟糕。 获取计数和索引:)

select  id
from    ( select id
          ,      row_number() over (order by id desc) idx
          ,      sum(1) over (order by null) cnt
          from   student
          group
          by     id
        )
where   idx = cnt - 1 -- get the pre-last

要么

where   idx = cnt - 2 -- get the 2nd-last

要么

where   idx = 3 -- get the 3rd

订购asc而不是desc

select id from student where rownum <=2 order by id asc;

尝试这个

SELECT * 
FROM (
  SELECT id, row_number() over (order by id asc) row_num
  FROM student
     ) AS T
WHERE row_num = 2 -- or 3 ... n

ROW_NUMBER

暂无
暂无

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

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