【问题标题】:Oracle SQL: Is it possible to create a table based on a selection and order by a column?Oracle SQL:是否可以根据列的选择和排序来创建表?
【发布时间】:2020-01-25 19:36:52
【问题描述】:

我想通过从另一个表中选择一些数据来创建一个表,同时根据一个(或多个)列对它们进行排序。我提供以下示例,知道它是错误的。一般是否可以实现这样的表格形成,如果可以,是否有任何类似的SQL语句可以实现?

CREATE TABLE NEW_TABLE_NAME AS (
SELECT
*
FROM A_RANDOM_TABLE
)
ORDER BY COLUMN_1,COLUMN_2;

【问题讨论】:

  • 表格代表无序集合,因此“按列排序”没有意义。
  • 您想在CTAS 中使用order by 实现什么目标?即使你的代码是错误的。应该是CREATE **TABLE** NEW_TABLE_NAME AS
  • 阅读本文的“CTAS using INDEX Hint”部分以及之后的部分。我不够熟悉,无法回答,但也许这会奏效。 dba-oracle.com/t_create_table_select_ctas.htm
  • @GordonLinoff 虽然根据定义堆表确实是无序的,但如果您使用有序集创建一个新表,则通常会以指定的顺序插入行(这与集群有关因素;块中属于单个索引条目的行越多,Oracle 检索指定值的行的速度就越快)。但是,之后插入的新行不会以“正确”的顺序插入;它们将被插入任何有空间的地方(例如,覆盖以前删除的行使用的间隔,或在表格的末尾)。
  • @Whitebeard13 这并不是不可能的,而是您认为这是错误的(我假设)。如果您想要的是,无论何时您从这个新表中选择返回的结果集都会被排序,那么您必须在您的 SELECT 语句中使用 ORDER BY 子句指定它。依赖表中记录的顺序在 SQL 中不会发生。仅在 SELECT 语句中的数据检索上进行排序。这里有一些例外,但它们是非常专业的用例,例如前面评论中提到的物联网。

标签: sql oracle datatable datatables


【解决方案1】:

可以使用Attribute Clustering 创建和维护物理表顺序。

CREATE TABLE NEW_TABLE_NAME
CLUSTERING BY LINEAR ORDER(COLUMN_1, COLUMN_2) AS
SELECT *
FROM A_RANDOM_TABLE
ORDER BY COLUMN_1, COLUMN_2;

虽然这确实回答了您的问题,但它可能不是您正在寻找的答案。属性聚类不是关于提供逻辑排序的。正如其他人指出的那样,保证排序的唯一方法是在查询中使用 ORDER BY 子句。我们不希望我们的表格与数据的物理格式紧密相关——这会导致问题,而这些问题最初正是创建关系模型的动机。

属性集群有助于提供物理排序以在多种情况下提高性能 - 索引集群因子、Exadata 中的物化区域映射等。属性集群有助于在MOVE 或直接路径INSERT 期间保持顺序。但是它并不维护所有DML语句的顺序,当然也不保证从表中读取结果的顺序。

【讨论】:

  • 这样能保证 select * from new_table_name 按顺序检索行吗?
  • @GordonLinoff 不,它不保证订单。
【解决方案2】:

您应该始终在查询时对数据进行排序。 保证 Oracle 会按照您插入数据的顺序实际存储数据。即使你会做这样的事情:

CREATE TABLE NEW_TABLE_NAME AS
  SELECT *
    FROM A_RANDOM_TABLE
   ORDER BY COLUMN_1,COLUMN_2
;

在 ASSM 表空间中(并且没有“附加”),Oracle 将在表中的任何位置寻找空闲槽。

【讨论】:

  • 。 .这会保证select * from new_table_name 按顺序检索行吗?
  • @ora-600 这是一个很好的答案。到目前为止,我做错了。当我创建这种SQL语句时,我在AS之后和;之前使用括号,即CREATE TABLE NEW_TABLE_NAME AS ( SELECT * FROM A_RANDOM_TABLE ORDER BY COLUMN1, COLUMN2 );这总是给我一个错误,并认为不可能同时创建和订购时间。在简化查询中使用它,有效!然而,在我的特殊情况下(我没有在我的主要问题中提供所有细节,因为我想让它简短)到目前为止它不起作用(见下一条评论)。
  • @ora-600 更具体地说,我的代码通过联合多个选择来创建一个表格。例如:CREATE TABLE NEW_TABLE_NAME AS SELECT * FROM A_RANDOM_TABLE_1 UNION ALL SELECT * FROM A_RANDOM_TABLE_2 UNION ALL SELECT * FROM A_RANDOM_TABLE_3 ORDER BY COLUMN1, COLUMN2 这给了我错误“ORA-00600:内部错误代码,参数:[qkeAddDependentExpr1], [], [], [], [], [], [], [], [], [],[],[]”。请注意,每个表中的列名相同且数据类型相同。
  • @GordonLinoff:在大多数情况下,这会以正确的顺序返回数据,但不能保证。但正确的解决方案是在读写期间ORDER BY
  • @Whitebeard13:您的 ora-600 听起来像错误 6530145(UNION ALL + ORDER BY)。 UNION 删除重复记录,从而导致数据的有序输出。如果您不必删除重复记录,请使用UNION ALL,这样会快得多。无论如何......从新表中选择时执行order by - 而不是在写入表时。这就是数据库的工作方式。
猜你喜欢
  • 2021-03-20
  • 1970-01-01
  • 2013-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-25
相关资源
最近更新 更多