2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

CREATE TABLE AS

CREATE TABLE AS — 从查询结果定义新表

概要

CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name
    [ (column_name [, ...] ) ]
    [ USING method ]
    [ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ]
    [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
    [ TABLESPACE tablespace_name ]
    AS query
    [ WITH [ NO ] DATA ]

描述

CREATE TABLE AS 创建一个表,并用 SELECT 命令计算出的数据填充它。表的列名和数据类型与 SELECT 的输出列相关联(除非通过显式提供新列名列表来覆盖列名)。

CREATE TABLE AS 在某种程度上类似于创建视图,但实际上有很大不同:它创建了一个新表,并只评估一次查询来最初填充新表。新表不会跟踪查询源表的后续更改。相比之下,视图在每次查询时都会重新评估其定义 SELECT 语句。

CREATE TABLE AS 需要在用于表的模式上拥有 CREATE 权限。

参数

GLOBALLOCAL

为兼容性而被忽略。这些关键字的使用已弃用;有关详细信息,请参阅 CREATE TABLE

TEMPORARYTEMP

如果指定,则表被创建为临时表。有关详细信息,请参阅 CREATE TABLE

UNLOGGED

如果指定,则表被创建为未记录的表。有关详细信息,请参阅 CREATE TABLE

IF NOT EXISTS

如果同名的关系已存在,则不报错;只发出一个通知并保持表不变。

table_name

要创建的表的名称(可以选择性地指定模式)。

column_name

新表中的列名。如果未提供列名,则从查询的输出列名中获取。

USING method

此可选子句指定用于存储新表内容的表访问方法;该方法必须是 TABLE 类型的访问方法。有关更多信息,请参阅 第 62 章。如果未指定此选项,则为新表选择默认表访问方法。有关更多信息,请参阅 default_table_access_method

WITH ( storage_parameter [= value] [, ... ] )

此子句指定新表的可选存储参数;有关更多信息,请参阅 存储参数 中的 CREATE TABLE 文档。为了向后兼容,表使用的 WITH 子句还可以包含 OIDS=FALSE 来指定新表的行不包含 OID(对象标识符),OIDS=TRUE 不再支持。

WITHOUT OIDS

这是声明表 WITHOUT OIDS 的向后兼容语法,创建表 WITH OIDS 不再支持。

ON COMMIT

临时表的事务块结束时的行为可以通过 ON COMMIT 进行控制。有三个选项:

PRESERVE ROWS

在事务结束时不做任何特殊操作。这是默认行为。

DELETE ROWS

在每个事务块结束时,临时表中的所有行都将被删除。实际上,在每次提交时都会执行一个自动的 TRUNCATE

DROP

临时表将在当前事务块结束时被删除。

TABLESPACE tablespace_name

tablespace_name 是要创建新表的表空间名称。如果未指定,则会咨询 default_tablespace,如果表是临时的,则会咨询 temp_tablespaces

query

一个 SELECTTABLEVALUES 命令,或者一个执行准备好的 SELECTTABLEVALUES 查询的 EXECUTE 命令。

WITH [ NO ] DATA

此子句指定是否将查询产生的数据复制到新表中。如果未复制,则只复制表结构。默认是复制数据。

注释

此命令在功能上与 SELECT INTO 类似,但更受推荐,因为它不太可能与 SELECT INTO 语法的其他用法混淆。此外,CREATE TABLE AS 提供了 SELECT INTO 所提供功能的一个超集。

示例

创建一个名为 films_recent 的新表,其中只包含 films 表中的近期条目

CREATE TABLE films_recent AS
  SELECT * FROM films WHERE date_prod >= '2002-01-01';

要完全复制表,也可以使用使用 TABLE 命令的简短形式

CREATE TABLE films2 AS
  TABLE films;

创建一个名为 films_recent 的新临时表,其中只包含 films 表中的近期条目,使用准备好的语句。新表将在提交时删除

PREPARE recentfilms(date) AS
  SELECT * FROM films WHERE date_prod > $1;
CREATE TEMP TABLE films_recent ON COMMIT DROP AS
  EXECUTE recentfilms('2002-01-01');

兼容性

CREATE TABLE AS 符合SQL标准。以下是非标准扩展:

  • 标准要求在子查询子句周围加上括号;在 PostgreSQL 中,这些括号是可选的。

  • 在标准中,WITH [ NO ] DATA 子句是必需的;在 PostgreSQL 中它是可选的。

  • PostgreSQL 处理临时表的方式与标准有很大不同;有关详细信息,请参阅 CREATE TABLE

  • WITH 子句是 PostgreSQL 的扩展;存储参数不在标准中。

  • PostgreSQL 的表空间概念不属于标准。因此,TABLESPACE 子句是一个扩展。

提交更正

如果您在文档中发现任何不正确、与您对特定功能的使用经验不符或需要进一步澄清的内容,请使用 此表单 来报告文档问题。