【问题标题】:Why = operator doesn't work with ROWNUM other than for value 1?为什么 = 运算符不能与 ROWNUM 一起使用,而不是值 1?
【发布时间】:2012-03-13 05:57:15
【问题描述】:

我有以下疑问:

select * from abc where rownum = 10

输出:没有要显示的记录

我确定 abc 表中有超过 25 条记录,我的目标是显示第 n 条记录。

如果我将查询写为: -

select * from abc where rownum = 1

它工作正常,给了我第一张唱片。除了第一条记录之外,没有任何其他记录。

有什么想法吗?

【问题讨论】:

    标签: sql oracle11g


    【解决方案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 分配给“真实”列,然后使用该真实列号过滤结果来实现。

    【讨论】:

    • 非常感谢。您能否提出任何替代方案来满足我的目标?也就是说,如果我知道n的值,显示第n条记录?
    • 非常感谢。 Oracle 文档这样说: UPDATE my_table SET column1 = ROWNUM;更好的是,我将在表中有一个真实的列,然后用它过滤结果。 :)
    • @SaharHassan,唯一的问题是你需要维护它。换句话说,您可能必须有触发器或自动增量列。但是,除非您明确对结果集进行排序,否则这些都无助于结果集本质上是 unsorted 的。
    • @paxdiablo 你知道我可以如何用 HQL 翻译你的第二个解决方案吗?它不接受内部选择的内部选择从子句和排序依据。所以我感到绝望!
    • @miss_R,不知道,我从未使用过 HQL。但是你知道谁有吗?可能这里有很多人无法回答,因为他们正在寻找问题而不是 cmets :-) 这是我(几乎没有)幽默的方式,如果你真的提出问题,你几乎肯定会得到更好的回应。
    猜你喜欢
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多