ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# CREATE TABLE AS ## Name CREATE TABLE AS -- 从一条查询的结果中定义一个新表 ## Synopsis ``` CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE _table_name_ [ (_column_name_ [, ...] ) ] [ WITH ( _storage_parameter_ [= _value_] [, ... ] ) | WITH OIDS | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE _tablespace_name_ ] AS _query_ [ WITH [ NO ] DATA ] ``` ## 描述 `CREATE TABLE AS`创建一个表并且用来自 `SELECT`命令的结果填充该表。该表的字段和 `SELECT`输出字段的名字及数据类型相关。 (不过你可以通过明确地给出一个字段名字列表来覆盖 SELECT 输出字段的名字。) `CREATE TABLE AS`和创建视图有点像, 不过两者之间实在是差异很大:它创建一个新表并且只对查询计算一次来填充这个新表。 新表不能跟踪源表的变化。相比之下,每次做查询的时候, 视图都重新计算定义它的`SELECT`语句。 ## 参数 `GLOBAL` 或 `LOCAL` 忽略,仅仅为了兼容性而存在。这些关键字的使用已经废弃了; 请参考[CREATE TABLE](#calibre_link-7)获取细节。 `TEMPORARY` 或 `TEMP` 如果声明了这个选项,则该表作为临时表创建。 参阅[CREATE TABLE](#calibre_link-7)获取细节。 `UNLOGGED` 如果声明了这个选项,则该表作为非日志表创建。 参阅[CREATE TABLE](#calibre_link-7)获取细节。 `_table_name_` 要创建的表名(可以用模式修饰)。 `_column_name_` 新表中字段的名称。如果没有提供字段名字,那么就从查询的输出字段名中获取。 `WITH (` `_storage_parameter_` [= `_value_`] [, ... ] ) 这个子句为新表指定了可选的存储参数;参见[_存储参数_](#calibre_link-86)获取更多信息。 `WITH`子句还可以包含`OIDS=TRUE`(或只是`OIDS`) 来为新表中的行分配和存储 OID(对象表示符);或者用`OIDS=FALSE` 表示不分配 OID 。参见[CREATE TABLE](#calibre_link-7)获取更多信息。 `WITH OIDS``WITHOUT OIDS` 这些是反对使用的、分别等价于`WITH (OIDS)`和 `WITH (OIDS=FALSE)`的语法。如果你希望同时给出`OIDS` 设置和存储参数,必须使用`WITH ( ... )`语法;见下文。 `ON COMMIT` 可以使用`ON COMMIT`控制临时表在事务块结尾的行为。 三个选项是: `PRESERVE ROWS` 在事务的结尾不采取任何特别的动作,这是缺省。 `DELETE ROWS` 在每个事务块的结尾都删除临时表中的所有行。 本质上是在每次提交事务后自动执行一个[TRUNCATE](#calibre_link-89)命令。 `DROP` 在当前事务块的结尾将删除临时表。 `TABLESPACE` `_tablespace_name_` 指定新表将要在`_tablespace_name_` 表空间内创建。如果没有声明,将咨询[default_tablespace](#calibre_link-90), 或如果该表为临时表,那么将使用[temp_tablespaces](#calibre_link-91)。 `_query_` 一个[SELECT](#calibre_link-104)、[TABLE](#calibre_link-105) 或[VALUES](#calibre_link-106)命令,或者一个运行预备好的 `SELECT`、`TABLE`或`VALUES` 查询的[EXECUTE](#calibre_link-107)命令。 `WITH [ NO ] DATA` 这个子句指定查询产生的数据是否应该拷贝到新表中。如果不,那么只拷贝表结构。 缺省是拷贝数据。 ## 注意 这条命令在功能上等效于[SELECT INTO](#calibre_link-108),但是更建议你用这个命令, 因为它不太可能和`SELECT INTO`语法的其它方面混淆。另外, `CREATE TABLE AS`提供了`SELECT INTO`功能的超集。 在PostgreSQL 8.0 之前, `CREATE TABLE AS`总是在它创建的表中包含 OID , 而在PostgreSQL 8.0 里,`CREATE TABLE AS` 命令允许明确声明是否应该包含 OID 。如果没有明确声明是否应该包含 OID , 那么使用配置变量[default_with_oids](#calibre_link-87)的设置。 到了PostgreSQL这个变量缺省为假, 缺省行为和 8.0 之前的版本不同。因此,那些要求`CREATE TABLE AS` 创建的表包含 OID 的应用应该明确声明`WITH (OIDS)`以确保要求的行为。 ## 例子 创建一个只包含表`films`中最近的记录的新表`films_recent`: ``` CREATE TABLE films_recent AS SELECT * FROM films WHERE date_prod >= '2002-01-01'; ``` 要完整的拷贝一个表,也可以使用`TABLE`命令的简易形式: ``` CREATE TABLE films2 AS TABLE films; ``` 使用预备语句创建一个只包含表`films`中最近的记录的新临时表 `films_recent`,该临时表包含 OID 并且在事务结束时将被删除: ``` PREPARE recentfilms(date) AS SELECT * FROM films WHERE date_prod > $1; CREATE TEMP TABLE films_recent WITH (OIDS) ON COMMIT DROP AS EXECUTE recentfilms('2002-01-01'); ``` ## 兼容性 `CREATE TABLE AS`兼容SQL标准, 下面是非标准的扩展: * 标准要求在子查询子句周围有圆括弧,在PostgreSQL 里,这些圆括弧是可选的。 * 在标准中,`WITH [ NO ] DATA`子句是必选的; 在PostgreSQL中,它是可选的。 * PostgreSQL处理临时表的方法和标准相差较大; 参阅[CREATE TABLE](#calibre_link-7)获取细节。 * `WITH`子句是PostgreSQL扩展, 并且 SQL 标准中也没有存储参数和 OID 。 * PostgreSQL表空间的概念也不是标准的一部分。 因此`TABLESPACE`子句也是扩展。 ## 又见 [CREATE MATERIALIZED VIEW](#calibre_link-109), [CREATE TABLE](#calibre_link-7), [EXECUTE](#calibre_link-107), [SELECT](#calibre_link-104), [SELECT INTO](#calibre_link-108), [VALUES](#calibre_link-106)