如果我从查询中移除<
符号,则以下查询未提供结果的原因。因为即使没有<
它也必须与结果匹配?
用于获取第二个最大ID值的查询:
select min(id)
from(
select distinct id
from student
order by id desc
)
where rownum <=2
student id
1
2
3
4
答案 0 :(得分:6)
Rownum在Oracle中具有特殊含义。它随着每一行而增加,但优化器知道它会不断增加,并且所有连续的行必须满足rownum条件。因此,如果您指定rownum = 2
,它将永远不会发生,因为第一行已被拒绝。
如果您对查询执行解释计划,您会发现这非常好。它将显示如下内容:
计划rownum <=
:
COUNT STOPKEY
计划rownum =
:
FILTER
答案 1 :(得分:1)
ROWNUM值未永久分配给一行(这是一种常见的误解)。表中的一行没有数字;你不能要求表格中的第2行或第3行 点击Here了解更多信息。
这是来自提供的链接:
对许多人来说,当实际分配ROWNUM值时也会感到困惑。 ROWNUM值在通过查询的谓词阶段之后但在查询执行任何排序或聚合之前分配给行。此外,ROWNUM值仅在分配后递增,这就是以下查询永远不会返回行的原因:
select *
from t
where ROWNUM > 1;
因为ROWNUM&gt; 1对于第一行不成立,ROWNUM不会前进到2.因此,ROWNUM值不会大于1.考虑具有此结构的查询:
select ..., ROWNUM
from t
where <where clause>
group by <columns>
having <having clause>
order by <columns>;
答案 2 :(得分:1)
我认为这是您正在寻找的查询:
select id
from (select distinct id
from student
order by id desc
) t
where rownum <= 2;
Oracle在rownum
之前处理order by
,因此您需要一个子查询来获取前两行。 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;
答案 3 :(得分:0)
为什么不使用
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
答案 4 :(得分:0)
订购asc而不是desc
select id from student where rownum <=2 order by id asc;
答案 5 :(得分:0)
试试这个
SELECT *
FROM (
SELECT id, row_number() over (order by id asc) row_num
FROM student
) AS T
WHERE row_num = 2 -- or 3 ... n