使用 CREATE TABLE 语句的 AS SELECT 子句创建新的表并插入指定查询的结果集的数据行。
此语法在功能上与 SELECT 语句的 INTO STANDARD 和 INTO RAW 子句 非常相似。
元素 | 描述 | 限制 | 语法 |
---|---|---|---|
column | 查询的 FROM 子句中的表的列。这将是结果表中的列名。 | 必须在查询结果集中存在 | 标识符 |
column_alias | 列的别名或显示标签。声明结果表中的列名称。 | 查询的 Projection 子句中的任何非平凡表达式在结果表中需要其列名的别名或显示标签 | 标识符 |
table | 此处为结果表声明的名称 | 在数据库中表、同义词、视图和序列名称中必须是唯一的。 | 标识符 |
target_data_type | 显式强制转型返回的数据类型。它将会是结果表中列的数据类型。 | 请参阅 对于目标数据类型的规则 | 数据类型 |
当使用 CREATE TABLE . . . AS SELECT 语句创建新的永久表来存储查询的结果时,您可以指定该表的日志记录方式为 STANDARD 或 RAW 。如果您都忽略了这些关键字,则缺省为 STANDARD 。
如果您省略了存储或锁定规范,则数据库服务器使用缺省值。
如果在数据库服务器向该表填充大量 AS SELECT 子句中查询返回的行时发生了错误,则该操作会回滚,且不会创建或填充新表。
出现在 AS SELECT 子句的 Projection 列表中的列可以来自任何本地表、视图或来自远程数据库(必须在限定的表名中引用),但是新表必须在本地数据库中创建。
在 grid 环境中,如果 AS SELECT 子句的 FROM 子句中的表与所有参与的指定的 grid 或地区的数据库服务器具有相同的结构,则您可以包含 AS SELECT 子句以从grid 查询创建表。
缺省情况下,新永久表中的列名称是在 Projection 子句的 SELECT 列表中指定的名称。如果星号(*)是 Projection 子句的 SELECT 列表,则星号将扩展为 SELECT 语句的 FROM 子句中对应的表或视图中的所有列名。由 FROM 子句指定表对象中的任何显式或隐式影子列不会由星号规范扩展。
在实现 Enterprise Replication 的系统上,可以使用 ALTER TABLE 语句的 ADD CRCOLS 、ADD REPLCHECK 和 ADD ERKEY 选项将相应的影子列添加到 AS SELECT 子句创建的结果表中。
除了简单列表达式之外, Projection 子句的 SELECT 列表中所有表达式都必须具有显示标签(也称为 列别名)。这用作新查询结果表中相应列的标识符。如果列表达式没有显示标签,则结果表使用查询的 FROM 子句中的源表中的列名。
如果在 CREATE TABLE . . . AS SELECT 语句中存在 Projection 子句的 SELECT 列表和 TABLE 关键字后面的逗号分隔的别名列表,则列别名的逗号分隔列表优先。在这种情况下,将忽略在 AS SELECT 子句中声明的任何列别名。
CREATE TABLE . . . AS SELECT 已经支持用户定义的数据类型和所有内置的 GBase 8s 数据类型。
但是,在新的结果表中只允许有一个序列列。在包含了第一个 SERIAL 、SERIAL8 或 BIGSERIAL 类型的列后,所有随后的 SERIAL 、SERIAL8 或 BIGSERIAL 列作为 INTEGER 、INTEGER8 或 BIGINTEGER 列创建。
与大多数 DDL 语句一样,使用完全限定表名在其它数据库中创建新结果表的尝试会失败,并显示语法错误。类似地,创建于现有表具有相同名称的结果表是一个错误,除非 AS SELECT 子句包含 IF NOT EXISTS 关键字。 SELECT 语句的 SELECT INTO . . . TABLE 语法作为子查询的一部分时是无效的。
AS SELECT 子句可以包含在 ORDER BY 子句中而不在 Projection 子句的 SELECT 列表中的列。
如果您在 AS SELECT 子句中为查询结果表声明的名称在数据库的永久表、同义词、视图和序列的名称中是唯一的,则无论 AS SELECT 子句是否包含 IF NOT EXISTS 关键字,数据库服务器总会创建查询结果表并填充所有查询返回的行。(如果查询没有返回行,则该结果表为空,但是它的结构已经在数据库的系统目录中注册,并作为一个新的永久表存在。)
0 row(s) retrieved into table.
如果 AS SELECT 子句忽略了 IF NOT EXISTS 关键字,且您为查询结果表声明的名称在数据库的永久表的名称中并不是唯一的,则不会创建结果表,并且数据库服务器返回一个错误。
以下示例创建了一个名为 rtabl 的新 RAW 表,用此表来存储连接查询的结果:
CREATE RAW TABLE IF NOT EXISTS rtab1 AS SELECT t1col1, t1col2, t2col1 FROM tab1, tab2 WHERE t1col1 < 100 and t2col1 > 5;
在以上示例中,新的查询结果表 rtab1 将包含列 t1col1 、t1col2 和 t2col1 。
下一个示例发生错误 -249 并失败,因为它没有为 col1+5 列表达式声明显示标签:
CREATE TABLE IF NOT EXISTS qtab1 AS SELECT col1+5, col2 FROM tab1;
通过在包含 + 运算符的 Projection 子句中为列表表达式声明列别名 qcol1,以下修订的查询避免了之前示例返回的 -249 错误:
CREATE TABLE IF NOT EXISTS qtab1 (qcol1, col2) AS SELECT col1+5, col2 FROM tab1;
以上正确的示例创建了标准表 qtabl 来存储 AS SELECT 子句的查询结果。
下一示例使用不同但等价的语句来在 AS SELECT 子句中声明相同的 qcol1 别名,而不是在列别名列表中声明:
CREATE TABLE IF NOT EXISTS qtab1 AS SELECT col1+5 qcol1, col2 FROM tab1;
以上的 CREATE TABLE 语句同样避免了 -249 错误,并创建结果和数据内容与前面示例中 qtabl 表相同的结果表。这这些示例中,结果表都有两列, qcol1 和 col2 。如果 col1 是 INTEGER 类型,则 qcol1 将是 DECIMAL 类型,返回的数据类型来自 col1+5 表达式。
如语法图所示,CREATE TABLE 语句的 Storage 和 Lock Mode 选项对 AS SELECT 子句有效。以下示例使用 FRAGMENT BY EXPRESSION 关键字为查询结果表定义分布存储策略,其中 fcol1 列别名是分片键,ROW 是锁定粒度:
CREATE TABLE IF NOT EXISTS permtab (fcol1, col2) FRAGMENT BY EXPRESSION fcol1 < 300 IN dbs1, fcol1 >=300 IN dbs2 LOCK MODE ROW AS SELECT col1::FLOAT, col2 FROM tab1;
任何 fcol1 值低于 300 的行会插入到 dbspace dbs1 中。具有较大 fcol1 值的行会存储在 dbs2 dbspace 中。