【发布时间】:2012-03-13 05:57:15
【问题描述】:
我有以下疑问:
select * from abc where rownum = 10
输出:没有要显示的记录
我确定 abc 表中有超过 25 条记录,我的目标是显示第 n 条记录。
如果我将查询写为: -
select * from abc where rownum = 1
它工作正常,给了我第一张唱片。除了第一条记录之外,没有任何其他记录。
有什么想法吗?
【问题讨论】:
我有以下疑问:
select * from abc where rownum = 10
输出:没有要显示的记录
我确定 abc 表中有超过 25 条记录,我的目标是显示第 n 条记录。
如果我将查询写为: -
select * from abc where rownum = 1
它工作正常,给了我第一张唱片。除了第一条记录之外,没有任何其他记录。
有什么想法吗?
【问题讨论】:
因为行号是按顺序分配给获取和返回的行。
这就是你的陈述的运作方式。它抓取第一个候选行并临时为其赋予第 1 行,这与您的条件不匹配,因此被丢弃。
然后你得到第二个候选行,它也给出了第 1 行(因为前一个被丢弃了)。也不匹配。
然后是第三个候选行......好吧,我相信你现在可以看到它的发展方向。简而言之,您永远找不到满足该条件的行。
行号仅对= 1、< something 或<= something 有用。
这在Oracle docs for the rownum pseudo-column中都有解释。
您还应该记住,SQL 是一种关系代数,除非您指定顺序,否则它会返回无序集。这意味着第 10 行可能是现在,三分钟后可能是别的。
如果您想要一种(不可否认的笨拙)方法来获得nth 行,您可以使用类似(对于第五行):
select * from (
select * from (
select col1, col2, col3 from tbl order by col1 asc
) where rownum < 6 order by col1 desc
) where rownum = 1
内部选择将确保您在开始丢弃行之前在查询中具有一致的顺序,而中间选择将丢弃除前五行之外的所有行,并且还会反转顺序。
然后外部选择将只返回反向集的第一行(当它按升序排列时,它是五行集的最后一行)。
更好的方法可能是:
select * from (
select rownum rn, col1, col2, col3 from tbl order by col1
) where rn = 5
这通过检索所有内容并将 rownum 分配给“真实”列,然后使用该真实列号过滤结果来实现。
【讨论】: