Oracle/SQL:为啥查询“SELECT * FROM records WHERE rownum >= 5 AND rownum <= 10” - 返回零行

Posted

技术标签:

【中文标题】Oracle/SQL:为啥查询“SELECT * FROM records WHERE rownum >= 5 AND rownum <= 10” - 返回零行【英文标题】:Oracle/SQL: Why does query "SELECT * FROM records WHERE rownum >= 5 AND rownum <= 10" - return zero rowsOracle/SQL:为什么查询“SELECT * FROM records WHERE rownum >= 5 AND rownum <= 10” - 返回零行 【发布时间】:2009-05-12 23:35:03 【问题描述】:

为什么以下查询返回“零”记录:

SELECT * FROM 记录 WHERE rownum >= 5 AND rownum = 5

而以下查询返回正确的记录:

SELECT * FROM 记录 WHERE rownum

问候, - 艾希什

【问题讨论】:

您始终可以使用减号从整个查询中减去 【参考方案1】:

在 Oracle 中,Rownum 值是在查询的过滤阶段之后分配的——它们不是表的行,而是查询结果集的行。

所以返回的第一行将始终为 rownum 1,返回的第二行为 rownum 2,依此类推。

rownum 值只有在赋值后才会递增,所以任何查询都像

select * from t where ROWNUM > 1

从不返回任何结果。这个查询说“我不想看到返回给我的第一行,只看到后面的那些”,这是一个悖论,所以什么都没有返回。

更多详情请见Ask Tom:On ROWNUM and Limiting Results。

【讨论】:

是否可以在更大的查询中访问子查询的 rownum?我怀疑这可能是最初的问题所在。 啊,我看到 Tom 在您链接的文章中的“使用 ROWNUM 分页”部分中解释了这一点。很好的链接! 嗯!!我想我可以使用“rownum”过滤掉任何记录子集。这是一个真正详细且内容丰富的答案 - 感谢“codeulike”的帮助。 令人尴尬的是,我所做的只是用谷歌搜索它并写一个总结——我使用的是 MS-SQL,而不是 Oracle。但现在这是我投票率最高的答案:)谢谢! 答案中的链接已损坏。这里的新链接:oracle.com/technetwork/issue-archive/2006/06-sep/…【参考方案2】:

ROWNUM 是一个伪列,它的值在查询执行时不可用。因此,您无法根据此列过滤结果。话虽如此,有一些变通方法可以减轻它。请看下面(如果你的结果非常大,不建议使用)。

Select a.* From 
(
  Select COL1, COL2, ROWNUM RowNumber From MyTable
) a
Where
   RowNumber = 5;

【讨论】:

【参考方案3】:

替代方法是使用MINUS

SELECT * FROM records 
WHERE   ROWNUM <= 10
minus SELECT * FROM records 
WHERE   ROWNUM <= 5

这将过滤掉非唯一值,因此您最好选择 id。

希望这可以为您节省一些时间。

【讨论】:

以上是关于Oracle/SQL:为啥查询“SELECT * FROM records WHERE rownum >= 5 AND rownum <= 10” - 返回零行的主要内容,如果未能解决你的问题,请参考以下文章

为啥我们在 Oracle SQL 中需要 SELECT FOR UPDATE?

Oracle, SQL Server, My SQL如何实现数据分页查询语句

oracle sql 基础:select 语句

Oracle SQL Select 中的行数?

Oracle SQL,在 SELECT 标头中的子查询中返回唯一(最大)行(在 FROM、WHERE 之前)

优化 Oracle SQL 查询