52

在 Oracle 中,如果未指定“order by”子句,则选择查询的默认行顺序是什么。

是吗

  1. 插入行的顺序
  2. 根本没有默认排序
  3. 以上都不是。
4

8 回答 8

48

根据 Tom Kyte 的说法:“除非并且直到您在查询中添加“order by”,否则您不能对返回的行的顺序说任何话。好吧,除了“您不能依赖返回的行的顺序”之外。

请在 asktom.com 上查看此问题。

至于ROWNUM,它在物理上并不存在,所以不能“释放”。ROWNUM 是在从表中检索到记录后分配的,这就是为什么“WHERE ROWNUM = 5”总是无法选择任何记录的原因。

@ammoQ:您可能想阅读这篇关于 GROUP BY 订购的 AskTom 文章。简而言之:

Query 中的 Group By 子句是否保证输出数据将按 Group By 列排序,即使没有 Order By 子句?

我们说...

绝对不,

它从来没有,它从来没有,它永远不会。

于 2009-05-22T21:39:37.813 回答
23

没有明确的默认排序。出于显而易见的原因,如果您创建一个新表,插入几行并执行没有“where”子句的“select *”,它将(很可能)按照插入的顺序返回行。

但是你永远不应该依赖默认订单的发生。如果您需要特定的订单,请使用“order by”子句。例如,在最高 9i 的 Oracle 版本中,执行“分组依据”也会导致行按组表达式 (*) 排序。在 10g 中,这种行为不再存在!因此,升级 Oracle 安装给我带来了一些工作。

(*) 免责声明:虽然这是我观察到的行为,但从未得到保证

于 2009-05-22T19:36:11.167 回答
6

已经说过,当您没有指定 ORDER BY 子句时,Oracle 可以按照它想要的任何顺序为您提供行。当您不指定 ORDER BY 子句时,推测订单将是什么是没有意义的。在你的代码中依赖它,是一个“职业限制举措”。

一个简单的例子:

SQL> create table t as select level id from dual connect by level <= 10
  2  /

Tabel is aangemaakt.

SQL> select id from t
  2  /

        ID
----------
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10

10 rijen zijn geselecteerd.

SQL> delete t where id = 6
  2  /

1 rij is verwijderd.

SQL> insert into t values (6)
  2  /

1 rij is aangemaakt.

SQL> select id from t
  2  /

        ID
----------
         1
         2
         3
         4
         5
         7
         8
         9
        10
         6

10 rijen zijn geselecteerd.

这只是在简单的删除+插入之后。还有许多其他可以想象的情况。并行执行、分区、索引组织表等等。

底线,正如 ammoQ 所说的那样:如果您需要对行进行排序,请使用 ORDER BY 子句。

于 2009-05-23T09:32:52.140 回答
4

除非您指定,否则您绝对不能依赖任何排序order by。特别是对于 Oracle,我实际上已经看到完全相同的查询(没有连接),在几秒钟内彼此运行两次,在一个临时没有更改的表上,返回一个完全不同的顺序。当结果集很大时,这似乎更有可能。

Rob van Wijk 提到的并行执行可能解释了这一点。另请参阅 Oracle 的Using Parallel Execution文档。

于 2013-03-26T18:50:43.010 回答
-2

它受索引的影响,如果有索引,它会返回一个升序,如果没有任何索引,它会返回插入的顺序。

于 2016-11-05T19:26:11.620 回答
-2

您可以使用 CREATE TABLE 语句的 ORGANIZATION 子句通过 INSERT 修改数据存储到表中的顺序

于 2017-11-29T16:45:31.910 回答
-3

虽然,它应该是 rownnum (你的 #2),但它真的不能保证,你不应该 100% 相信它。

于 2009-05-22T19:36:15.067 回答
-7

我相信它使用了 Oracle 的隐藏 Rownum 属性。

所以你的#1 可能是正确的,假设没有删除可能已经释放 rownums 供以后使用。

编辑:正如其他人所说,你真的不应该依赖这个,永远。除了删除之外,还有许多不同的条件会影响默认排序行为。

于 2009-05-22T19:15:11.333 回答