我对所有的常见问题及的HOWTOs建议Oracle数据库的规范前N个查询:rownum的订单 - 它是否正确?
select ... from (
select ... from ... order by ...
) where ronwum <= N
它完美对甲骨文11,即它在内部选择指定的顺序返回前N个记录。
然而,它在Oracle 12上打破了。它仍然返回相同的top-N记录,但它们可能会被混洗。这些记录的最终顺序是非确定性的。
我使用Google搜索,但没有找到任何相关的讨论。看起来其他人总是从这样的选择中获得正确的记录顺序。
虽然有一个发现很有趣。我看到一些人使用(不解释,可惜)外的额外order by rownum
条款选择:
select ... from (
select ... from ... order by ...
) where ronwum <= N
order by rownum
(包括ROWNUM在这里是对Oracle虚列引用,它是由内选择返回不的东西)
它似乎工作。但是使用Oracle优化器,您永远无法确定它是否只是运气或者真正正确的解决方案。
问题是:order by rownum
在这种情况下是否保证正确的排序顺序,为什么?我和我的同事们无法就此达成一致。
P.S.我知道其他的方式来选择前N个记录,例如使用row_number解析函数和Oracle 12中引入的fetch first
子句。我也知道,我可以在外层select上重复相同的order by ...
。问题仅在于order by rownum
- 是否正确。
我认为你需要重命名'rownum'的东西在内部不同select,否则外部引用引用rownum作为外部查询,而不引用内部查询。 –
执行此操作的正确方法是按外部查询中的相同表达式进行排序,就像您在子查询中所做的那样。即使在Oracle 11和之前的版本中,从内部查询到外部查询的顺序被保留的事实也是一个实现意外事件 - 它不能保证SQL标准。 – mathguy