

 从补丁 198 开始，Amazon Redshift 将不再支持创建新的 Python UDF。现有的 Python UDF 将继续正常运行至 2026 年 6 月 30 日。有关更多信息，请参阅[博客文章](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)。

# SQL 命令
<a name="c_SQL_commands"></a>

SQL 语言包括各种命令，您可以使用这些命令来创建和处理数据库对象、运行查询、加载表和修改表中的数据。

Amazon Redshift 基于 PostgreSQL。Amazon Redshift 和 PostgreSQL 之间的差别非常大，您在设计和开发数据仓库应用程序时必须注意这一点。有关 Amazon Redshift SQL 与 PostgreSQL 之间的差异的更多信息，请参阅[Amazon Redshift 和 PostgreSQL](c_redshift-and-postgres-sql.md)。

**注意**  
单个 SQL 语句的最大大小为 16MB。

**Topics**
+ [ABORT](r_ABORT.md)
+ [ALTER DATABASE](r_ALTER_DATABASE.md)
+ [ALTER DATASHARE](r_ALTER_DATASHARE.md)
+ [ALTER DEFAULT PRIVILEGES](r_ALTER_DEFAULT_PRIVILEGES.md)
+ [ALTER EXTERNAL SCHEMA](r_ALTER_EXTERNAL_SCHEMA.md)
+ [ALTER EXTERNAL VIEW](r_ALTER_EXTERNAL_VIEW.md)
+ [ALTER FUNCTION](r_ALTER_FUNCTION.md)
+ [ALTER GROUP](r_ALTER_GROUP.md)
+ [ALTER IDENTITY PROVIDER](r_ALTER_IDENTITY_PROVIDER.md)
+ [ALTER MASKING POLICY](r_ALTER_MASKING_POLICY.md)
+ [ALTER MATERIALIZED VIEW](r_ALTER_MATERIALIZED_VIEW.md)
+ [ALTER RLS POLICY](r_ALTER_RLS_POLICY.md)
+ [ALTER ROLE](r_ALTER_ROLE.md)
+ [ALTER PROCEDURE](r_ALTER_PROCEDURE.md)
+ [ALTER SCHEMA](r_ALTER_SCHEMA.md)
+ [ALTER SYSTEM](r_ALTER_SYSTEM.md)
+ [ALTER TABLE](r_ALTER_TABLE.md)
+ [ALTER TABLE APPEND](r_ALTER_TABLE_APPEND.md)
+ [ALTER TEMPLATE](r_ALTER_TEMPLATE.md)
+ [ALTER USER](r_ALTER_USER.md)
+ [ANALYZE](r_ANALYZE.md)
+ [ANALYZE COMPRESSION](r_ANALYZE_COMPRESSION.md)
+ [ATTACH MASKING POLICY](r_ATTACH_MASKING_POLICY.md)
+ [ATTACH RLS POLICY](r_ATTACH_RLS_POLICY.md)
+ [BEGIN](r_BEGIN.md)
+ [CALL](r_CALL_procedure.md)
+ [CANCEL](r_CANCEL.md)
+ [CLOSE](close.md)
+ [COMMENT](r_COMMENT.md)
+ [COMMIT](r_COMMIT.md)
+ [COPY](r_COPY.md)
+ [CREATE DATABASE](r_CREATE_DATABASE.md)
+ [CREATE DATASHARE](r_CREATE_DATASHARE.md)
+ [CREATE EXTERNAL FUNCTION](r_CREATE_EXTERNAL_FUNCTION.md)
+ [CREATE EXTERNAL MODEL](r_create_external_model.md)
+ [CREATE EXTERNAL SCHEMA](r_CREATE_EXTERNAL_SCHEMA.md)
+ [CREATE EXTERNAL TABLE](r_CREATE_EXTERNAL_TABLE.md)
+ [CREATE EXTERNAL VIEW](r_CREATE_EXTERNAL_VIEW.md)
+ [CREATE FUNCTION](r_CREATE_FUNCTION.md)
+ [CREATE GROUP](r_CREATE_GROUP.md)
+ [CREATE IDENTITY PROVIDER](r_CREATE_IDENTITY_PROVIDER.md)
+ [CREATE LIBRARY](r_CREATE_LIBRARY.md)
+ [CREATE MASKING POLICY](r_CREATE_MASKING_POLICY.md)
+ [CREATE MATERIALIZED VIEW](materialized-view-create-sql-command.md)
+ [CREATE MODEL](r_CREATE_MODEL.md)
+ [CREATE PROCEDURE](r_CREATE_PROCEDURE.md)
+ [CREATE RLS POLICY](r_CREATE_RLS_POLICY.md)
+ [CREATE ROLE](r_CREATE_ROLE.md)
+ [CREATE SCHEMA](r_CREATE_SCHEMA.md)
+ [CREATE TABLE](r_CREATE_TABLE_NEW.md)
+ [CREATE TABLE AS](r_CREATE_TABLE_AS.md)
+ [CREATE TEMPLATE](r_CREATE_TEMPLATE.md)
+ [CREATE USER](r_CREATE_USER.md)
+ [CREATE VIEW](r_CREATE_VIEW.md)
+ [DEALLOCATE](r_DEALLOCATE.md)
+ [DECLARE](declare.md)
+ [DELETE](r_DELETE.md)
+ [DESC DATASHARE](r_DESC_DATASHARE.md)
+ [DESC IDENTITY PROVIDER](r_DESC_IDENTITY_PROVIDER.md)
+ [DETACH MASKING POLICY](r_DETACH_MASKING_POLICY.md)
+ [DETACH RLS POLICY](r_DETACH_RLS_POLICY.md)
+ [DROP DATABASE](r_DROP_DATABASE.md)
+ [DROP DATASHARE](r_DROP_DATASHARE.md)
+ [DROP EXTERNAL VIEW](r_DROP_EXTERNAL_VIEW.md)
+ [DROP FUNCTION](r_DROP_FUNCTION.md)
+ [DROP GROUP](r_DROP_GROUP.md)
+ [DROP IDENTITY PROVIDER](r_DROP_IDENTITY_PROVIDER.md)
+ [DROP LIBRARY](r_DROP_LIBRARY.md)
+ [DROP MASKING POLICY](r_DROP_MASKING_POLICY.md)
+ [DROP MODEL](r_DROP_MODEL.md)
+ [DROP MATERIALIZED VIEW](materialized-view-drop-sql-command.md)
+ [DROP PROCEDURE](r_DROP_PROCEDURE.md)
+ [DROP RLS POLICY](r_DROP_RLS_POLICY.md)
+ [DROP ROLE](r_DROP_ROLE.md)
+ [DROP SCHEMA](r_DROP_SCHEMA.md)
+ [DROP TABLE](r_DROP_TABLE.md)
+ [DROP TEMPLATE](r_DROP_TEMPLATE.md)
+ [DROP USER](r_DROP_USER.md)
+ [DROP VIEW](r_DROP_VIEW.md)
+ [END](r_END.md)
+ [EXECUTE](r_EXECUTE.md)
+ [EXPLAIN](r_EXPLAIN.md)
+ [FETCH](fetch.md)
+ [GRANT](r_GRANT.md)
+ [INSERT](r_INSERT_30.md)
+ [INSERT（外部表）](r_INSERT_external_table.md)
+ [LOCK](r_LOCK.md)
+ [MERGE](r_MERGE.md)
+ [PREPARE](r_PREPARE.md)
+ [REFRESH MATERIALIZED VIEW](materialized-view-refresh-sql-command.md)
+ [RESET](r_RESET.md)
+ [REVOKE](r_REVOKE.md)
+ [ROLLBACK](r_ROLLBACK.md)
+ [SELECT](r_SELECT_synopsis.md)
+ [SELECT INTO](r_SELECT_INTO.md)
+ [SET](r_SET.md)
+ [SET SESSION AUTHORIZATION](r_SET_SESSION_AUTHORIZATION.md)
+ [SET SESSION CHARACTERISTICS](r_SET_SESSION_CHARACTERISTICS.md)
+ [SHOW](r_SHOW.md)
+ [SHOW COLUMN GRANTS](r_SHOW_COLUMN_GRANTS.md)
+ [SHOW COLUMNS](r_SHOW_COLUMNS.md)
+ [SHOW CONSTRAINTS](r_SHOW_CONSTRAINTS.md)
+ [SHOW EXTERNAL TABLE](r_SHOW_EXTERNAL_TABLE.md)
+ [SHOW DATABASES](r_SHOW_DATABASES.md)
+ [SHOW FUNCTIONS](r_SHOW_FUNCTIONS.md)
+ [SHOW GRANTS](r_SHOW_GRANTS.md)
+ [SHOW MODEL](r_SHOW_MODEL.md)
+ [SHOW DATASHARES](r_SHOW_DATASHARES.md)
+ [SHOW PARAMETERS](r_SHOW_PARAMETERS.md)
+ [SHOW POLICIES](r_SHOW_POLICIES.md)
+ [SHOW PROCEDURE](r_SHOW_PROCEDURE.md)
+ [SHOW PROCEDURES](r_SHOW_PROCEDURES.md)
+ [SHOW SCHEMAS](r_SHOW_SCHEMAS.md)
+ [SHOW TABLE](r_SHOW_TABLE.md)
+ [SHOW TABLES](r_SHOW_TABLES.md)
+ [SHOW TEMPLATE](r_SHOW_TEMPLATE.md)
+ [SHOW TEMPLATES](r_SHOW_TEMPLATES.md)
+ [SHOW VIEW](r_SHOW_VIEW.md)
+ [START TRANSACTION](r_START_TRANSACTION.md)
+ [TRUNCATE](r_TRUNCATE.md)
+ [UNLOAD](r_UNLOAD.md)
+ [UPDATE](r_UPDATE.md)
+ [USE](r_USE_command.md)
+ [VACUUM](r_VACUUM_command.md)

# ABORT
<a name="r_ABORT"></a>

停止当前正在运行的事务，并放弃该事务执行的所有更新。ABORT 对已完成的事务没有任何效果。

此命令执行与 ROLLBACK 命令相同的功能。有关信息，请参阅 [ROLLBACK](r_ROLLBACK.md)。

## 语法
<a name="r_ABORT-synopsis"></a>

```
ABORT [ WORK | TRANSACTION ]
```

## 参数
<a name="r_ABORT-parameters"></a>

WORK  
可选关键字。

TRANSACTION  
可选关键字；WORK 和 TRANSACTION 同义。

## 示例
<a name="r_ABORT-example"></a>

以下示例创建一个表，然后启动将数据插入到表的事务。然后，ABORT 命令将回滚数据插入操作，以便将表保持为空表。

以下命令创建一个名为 MOVIE\$1GROSS 的示例表：

```
create table movie_gross( name varchar(30), gross bigint );
```

下一组命令启动将两个数据行插入到表中的事务：

```
begin;

insert into movie_gross values ( 'Raiders of the Lost Ark', 23400000);

insert into movie_gross values ( 'Star Wars', 10000000 );
```

接下来，以下命令从表中选择数据，表明已插入成功：

```
select * from movie_gross;
```

命令输出表明已成功插入两行：

```
         name           |  gross
------------------------+----------
Raiders of the Lost Ark | 23400000
Star Wars               | 10000000
(2 rows)
```

现在，此命令将数据更改回滚到事务开始的位置：

```
abort;
```

现在，从表中选择数据时，显示这是一个空表：

```
select * from movie_gross;

 name | gross
------+-------
(0 rows)
```

# ALTER DATABASE
<a name="r_ALTER_DATABASE"></a>

更改数据库的属性。

## 所需的权限
<a name="r_ALTER_DATABASE-privileges"></a>

要使用 ALTER DATABASE，需要以下权限之一。
+ Superuser
+ 具有 ALTER DATABASE 权限的用户
+ 数据库拥有者

## 语法
<a name="r_ALTER_DATABASE-synopsis"></a>

```
ALTER DATABASE database_name
{ 
  RENAME TO new_name
  | OWNER TO new_owner
  | [ CONNECTION LIMIT { limit | UNLIMITED } ]
    [ COLLATE { CASE_SENSITIVE | CS | CASE_INSENSITIVE | CI } ]
    [ ISOLATION LEVEL { SNAPSHOT | SERIALIZABLE } ]
| INTEGRATION
 { 
  REFRESH { { ALL | INERROR } TABLES [ IN SCHEMA schema [, ...] ] | TABLE schema.table [, ...] }
   | SET 
     [ QUERY_ALL_STATES [=] { TRUE | FALSE } ] 
     [ ACCEPTINVCHARS [=] { TRUE | FALSE } ] 
     [ REFRESH_INTERVAL <interval> ]
     [ TRUNCATECOLUMNS [=] { TRUE | FALSE } ]
     [ HISTORY_MODE [=] {TRUE | FALSE} [ FOR { {ALL} TABLES [IN SCHEMA schema [, ...] ] | TABLE schema.table [, ...] } ] ]
 }
}
```

## 参数
<a name="r_ALTER_DATABASE-parameters"></a>

 *database\$1name*   
要更改的数据库的名称。通常，您将更改当前未连接到的数据库；在任何情况下，更改只在后续的会话中才会生效。您可以更改当前数据库的所有者，但不能重命名该数据库：  

```
alter database tickit rename to newtickit;
ERROR:  current database may not be renamed
```

RENAME TO   
重命名指定的数据库。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。不能重命名 dev、padb\$1harvest、template0、template1 或 sys:internal 数据库，也不能重命名当前数据库。只有数据库所有者或 [superuser](r_superusers.md#def_superusers) 可以重命名数据库；非超级用户所有者还必须具有 CREATEDB 权限。

 *new\$1name*   
新数据库名称。

OWNER TO   
更改指定数据库的所有者。您可以更改当前数据库或其他某个数据库的所有者。只有超级用户可以更改所有者。

 *new\$1owner*   
新数据库所有者。新所有者必须是具有写入权限的现有数据库用户。有关用户权限的更多信息，请参阅[GRANT](r_GRANT.md)。

CONNECTION LIMIT \$1 *limit* \$1 UNLIMITED \$1   
允许用户同时打开的数据库连接的最大数量。此限制不适用于超级用户。使用 UNLIMITED 关键字设置允许的并行连接的最大数量。可能对每个用户的连接数量也会施加限制。有关更多信息，请参阅 [CREATE USER](r_CREATE_USER.md)。默认为 UNLIMITED。要查看当前连接，请查询 [STV\$1SESSIONS](r_STV_SESSIONS.md) 系统视图。  
如果用户及数据库连接限制均适用，当用户尝试连接时，必须有一个同时低于这两个限制的未使用的连接槽可用。

COLLATE \$1 CASE\$1SENSITIVE \$1 CS \$1 CASE\$1INSENSITIVE \$1 CI \$1  
指定字符串搜索或比较是区分大小写还是不区分大小写的子句。  
您可以更改当前数据库的区分大小写，即使数据库为空也是如此。  
您必须对当前数据库具有 ALTER 权限，才能更改区分大小写设置。具有 CREATE DATABASE 权限的超级用户或数据库拥有者也可以更改数据库的区分大小写设置。  
CASE\$1SENSITIVE 和 CS 可以互换，生成的结果相同。同样，CASE\$1INSENSITIVE 和 CI 可以互换，生成的结果相同。

ISOLATION LEVEL \$1 SNAPSHOT \$1 SERIALIZABLE \$1  
指定针对数据库运行查询时使用的隔离级别的子句。有关隔离级别的更多信息，请参阅[Amazon Redshift 中的隔离级别](c_serial_isolation.md)。  
+ SNAPSHOT 隔离 – 提供隔离级别，来防止出现更新和删除冲突。
+ SERIALIZABLE 隔离–为并发事务提供完全可序列性。
更改数据库的隔离级别时，请考虑以下项目：  
+ 您必须对当前数据库具有超级用户或 CREATE DATABASE 权限，才能更改数据库隔离级别。
+ 您不能更改 `dev` 数据库的隔离级别。
+ 您不能更改事务块中的隔离级别。
+ 如果有其他用户连接到数据库，则更改隔离级别命令将失败。
+ 更改隔离级别命令可以更改当前会话的隔离级别设置。

INTEGRATION  
更改零 ETL 集成数据库。

REFRESH \$1\$1 ALL \$1 INERROR \$1 TABLES [IN SCHEMA *schema* [, ...]] \$1 TABLE *schema.table* [, ...]\$1  
指定 Amazon Redshift 是否刷新指定架构或表中的所有表或有错误的表的子句。刷新将触发从源数据库完全复制指定架构或表中的表。  
有关更多信息，请参阅《Amazon Redshift 管理指南》**中的[零 ETL 集成](https://docs.aws.amazon.com/redshift/latest/mgmt/zero-etl-using.html)。有关集成状态的更多信息，请参阅[SVV\$1INTEGRATION\$1TABLE\$1STATE](r_SVV_INTEGRATION_TABLE_STATE.md)和[SVV\$1INTEGRATION](r_SVV_INTEGRATION.md)。

QUERY\$1ALL\$1STATES [=] \$1 TRUE \$1 FALSE \$1  
QUERY\$1ALL\$1STATES 子句设置是否可以在所有状态（`Synced`、`Failed`、`ResyncRequired` 和 `ResyncInitiated`）下查询零 ETL 集成表。默认情况下，只能在 `Synced` 状态下查询零 ETL 集成表。

ACCEPTINVCHARS [=] \$1 TRUE \$1 FALSE \$1  
ACCEPTINVCHARS 子句设置在检测到 VARCHAR 数据类型的无效字符时，零 ETL 集成表是否继续摄取。在遇到无效字符时，无效字符将被替换为默认 `?` 字符。

REFRESH\$1INTERVAL <interval>  
REFRESH\$1INTERVAL 子句设置将数据从零 ETL 源刷新到目标数据库的大致时间间隔（秒）。对于源类型为 Aurora MySQL、Aurora PostgreSQL 或 RDS for MySQL 的零 ETL 集成，`interval` 可设置为 0-432000 秒（5 天）。对于 Amazon DynamoDB 零 ETL 集成，`interval` 可设置为 900-432000 秒（15 分钟 - 5 天）。  
有关使用零 ETL 集成创建数据库的更多信息，请参阅*《Amazon Redshift 管理指南》*中的[在 Amazon Redshift 中创建目标数据库](https://docs.aws.amazon.com/redshift/latest/mgmt/zero-etl-using.creating-db.html)。

TRUNCATECOLUMNS [=] \$1 TRUE \$1 FALSE \$1  
TRUNCATECOLUMNS 子句设置当 VARCHAR 列或 SUPER 列属性的值超出限制时，零 ETL 集成表是否继续摄取。当为 `TRUE` 时，值会被截断以适合该列，而溢出的 JSON 属性的值会被截断以适合 SUPER 列。

HISTORY\$1MODE [=] \$1TRUE \$1 FALSE\$1 [ FOR \$1 \$1ALL\$1 TABLES [IN SCHEMA schema [, ...]] \$1 TABLE schema.table [, ...]\$1 ]  
一个子句，用于指定 Amazon Redshift 是否为所有表或指定架构中参与零 ETL 集成的表设置历史记录模式。此选项仅适用于为零 ETL 集成创建的数据库。  
HISTORY\$1MODE 子句可设置为 `TRUE` 或 `FALSE`。默认值为 `FALSE`。启用和禁用历史记录模式仅适用于处于 `Synced` 状态的表。有关 HISTORY\$1MODE 的信息，请参阅《Amazon Redshift 管理指南》**中的[历史记录模式](https://docs.aws.amazon.com/redshift/latest/mgmt/zero-etl-history-mode.html)。

## 使用说明
<a name="r_ALTER_DATABASE-usage-notes"></a>

ALTER DATABASE 命令应用于后续会话，而不应用于当前会话。您必须重新连接到更改后的数据库，以查看更改结果。

## 示例
<a name="r_ALTER_DATABASE-examples"></a>

以下示例将一个名为 TICKIT\$1SANDBOX 的数据库重命名为 TICKIT\$1TEST：

```
alter database tickit_sandbox rename to tickit_test;
```

以下示例将 TICKIT 数据库（当前数据库）的所有者更改为 DWUSER：

```
alter database tickit owner to dwuser;
```

以下示例更改了 sampledb 数据库的数据库区分大小写：

```
ALTER DATABASE sampledb COLLATE CASE_INSENSITIVE;
```

以下示例使用 SNAPSHOT 隔离级别更改名为 **sampledb** 的数据库。

```
ALTER DATABASE sampledb ISOLATION LEVEL SNAPSHOT;
```

以下示例刷新零 ETL 集成的数据库 **sample\$1integration\$1db** 中的表 **schema1.sample\$1table1** 和 **schema2.sample\$1table2**。

```
ALTER DATABASE sample_integration_db INTEGRATION REFRESH TABLE schema1.sample_table1, schema2.sample_table2;
```

以下示例刷新零 ETL 集成中所有已同步和失败的表。

```
ALTER DATABASE sample_integration_db INTEGRATION REFRESH ALL tables;
```

下面的示例将零 ETL 集成的刷新间隔设置为 600 秒。

```
ALTER DATABASE sample_integration_db INTEGRATION SET REFRESH_INTERVAL 600;
```

下面的示例刷新架构 **sample\$1schema** 中处于 `ErrorState` 的所有表。

```
ALTER DATABASE sample_integration_db INTEGRATION REFRESH INERROR TABLES in SCHEMA sample_schema;
```

以下示例为表 `myschema.table1` 启用历史记录模式。

```
ALTER DATABASE sample_integration_db INTEGRATION SET HISTORY_MODE = true FOR TABLE myschema.table1
```

以下示例为 `myschema` 中的所有表启用历史记录模式。

```
ALTER DATABASE sample_integration_db INTEGRATION SET HISTORY_MODE = true for ALL TABLES IN SCHEMA myschema
```

# ALTER DATASHARE
<a name="r_ALTER_DATASHARE"></a>

更改数据共享的定义。您可以使用 ALTER DATASHARE 添加对象或删除对象。您只能更改当前数据库中的数据共享。将对象从关联数据库添加到数据共享中或者从数据共享中删除对象。对要添加或删除的数据共享具有所需权限的数据共享拥有者可以更改数据共享。

## 所需的权限
<a name="r_ALTER_DATASHARE-privileges"></a>

以下是 ALTER DATASHARE 所需的权限：
+ 超级用户。
+ 具有 ALTER DATASHARE 权限的用户。
+ 对数据共享具有 ALTER 或 ALL 权限的用户。
+ 要将特定对象添加到数据共享中，用户必须具有对象的权限。在此例中，用户应是对象的拥有者，或者具有这些对象的 SELECT、USAGE 或 ALL 权限。

## 语法
<a name="r_ALTER_DATASHARE-synopsis"></a>

以下语法展示了如何向数据共享添加或删除对象。

```
ALTER DATASHARE datashare_name { ADD | REMOVE } {
TABLE schema.table [, ...]
| SCHEMA schema [, ...]
| FUNCTION schema.sql_udf (argtype,...) [, ...]
| ALL TABLES IN SCHEMA schema [, ...]
| ALL FUNCTIONS IN SCHEMA schema [, ...] }
```

以下语法展示了如何配置数据共享的属性。

```
ALTER DATASHARE datashare_name {
[ SET PUBLICACCESSIBLE [=] TRUE | FALSE ]
[ SET INCLUDENEW [=] TRUE | FALSE FOR SCHEMA schema ] }
```

## 参数
<a name="r_ALTER_DATASHARE-parameters"></a>

*datashare\$1name*  
要更改的数据共享的名称。

ADD \$1 REMOVE  
指定是向数据集中添加对象还是从中删除对象的子句。

TABLE *schema*.*table* [, ...]  
要添加到数据共享的指定 schema 中的表或视图的名称。

SCHEMA *schema* [, ...]   
要添加到数据共享中的 schema 的名称。

FUNCTION *schema*.*sql\$1udf* (argtype,...) [, ...]  
要添加到数据共享的用户定义的 SQL 函数的名称和参数类型。

ALL TABLES IN SCHEMA *schema* [, ...]   
指定是否将指定 schema 中的所有表和视图添加到数据共享中的子句。

ALL FUNCTIONS IN SCHEMA *schema* [, ...] \$1  
指定将指定 schema 中的所有函数添加到数据共享中的子句。

[ SET PUBLICACCESSIBLE [=] TRUE \$1 FALSE ]  
指定是否可以将数据共享共享给可公开访问的集群的子句。

[ SET INCLUDENEW [=] TRUE \$1 FALSE FOR SCHEMA *schema* ]  
指定是否将在指定 schema 中创建的任何未来表、视图或 SQL 用户定义函数 (UDF) 添加到数据共享中的子句。指定 schema 中的当前表、视图或 SQL UDF 不会添加到数据共享中。只有超级用户才可以更改每个数据共享-schema 对的此属性。预设情况下，INCLUDENEW 子句为 false。

## ALTER DATASHARE 使用说明
<a name="r_ALTER_DATASHARE_usage"></a>
+ 以下用户可以更改数据共享：
  + 超级用户
  + 数据共享的拥有者
  + 对数据共享具有 ALTER 或 ALL 权限的用户
+ 要将特定对象添加到数据共享中，用户必须具有对象的正确权限。用户应该是对象的拥有者，或者对这些对象具有 SELECT、USAGE 或 ALL 权限。
+ 您可以共享 schema、表、常规视图、后期绑定视图、实体化视图和 SQL 用户定义函数 (UDF)。在架构中添加对象之前，首先将架构添加到数据共享中。

  当您添加 schema 时，Amazon Redshift 不会在其下添加所有对象。您必须显式添加它们。
+ 我们建议您在可公开访问的设置处于开启状态下创建 AWS Data Exchange 数据共享。
+ 通常，我们不建议您使用 ALTER DATASHARE 语句更改 AWS Data Exchange 数据共享，以关闭公开可访问性。如果您这样做的话，如果其集群可以公开访问，有权访问数据共享的 AWS 账户 将失去访问权限。执行这种类型的更改可能会违反 AWS Data Exchange 中的数据产品条款。对于此建议的例外情况，请参阅以下内容。

  以下示例显示了设置处于关闭状态下创建 AWS Data Exchange 数据共享时发生的错误。

  ```
  ALTER DATASHARE salesshare SET PUBLICACCESSIBLE FALSE;
  ERROR:  Alter of ADX-managed datashare salesshare requires session variable datashare_break_glass_session_var to be set to value 'c670ba4db22f4b'
  ```

  要允许更改 AWS Data Exchange 数据共享，以禁用可公开访问的设置，请设置以下变量，然后再次运行 ALTER DATASHARE 语句。

  ```
  SET datashare_break_glass_session_var to 'c670ba4db22f4b';
  ```

  ```
  ALTER DATASHARE salesshare SET PUBLICACCESSIBLE FALSE;
  ```

  在这种情况下，Amazon Redshift 会生成一个随机的一次性值来设置会话变量，以允许对 AWS Data Exchange 数据共享执行 ALTER DATASHARE SET PUBLICACCESSIBLE FALSE。

## 示例
<a name="r_ALTER_DATASHARE_examples"></a>

以下示例将 `public` 架构添加到数据共享 `salesshare` 中。

```
ALTER DATASHARE salesshare ADD SCHEMA public;
```

以下示例将 `public.tickit_sales_redshift` 表添加到了数据共享 `salesshare` 中。

```
ALTER DATASHARE salesshare ADD TABLE public.tickit_sales_redshift;
```

以下示例将所有表添加到了数据共享 `salesshare` 中。

```
ALTER DATASHARE salesshare ADD ALL TABLES IN SCHEMA PUBLIC;
```

以下示例删除了数据共享 `salesshare` 中的 `public.tickit_sales_redshift` 表。

```
ALTER DATASHARE salesshare REMOVE TABLE public.tickit_sales_redshift;
```

# ALTER DEFAULT PRIVILEGES
<a name="r_ALTER_DEFAULT_PRIVILEGES"></a>

定义默认访问权限集，这些权限将应用于指定的用户在以后创建的对象。默认情况下，用户只能更改他们自己的默认访问权限。只有超级用户能够为其他用户指定默认权限。

您可以将默认权限应用到角色、用户或用户组。您可以为在当前数据库中创建的所有对象全局设置默认权限，也可以仅为在指定的架构中创建的对象进行此设置。

默认权限仅应用于新对象。运行 ALTER DEFAULT PRIVILEGES 时不会更改现有对象的权限。要授予对数据库或架构中任何用户创建的所有当前和将来对象的权限，请参阅[限定范围权限](https://docs.aws.amazon.com/redshift/latest/dg/t_scoped-permissions.html)。

要查看有关数据库用户的默认权限的信息，请查询 [PG\$1DEFAULT\$1ACL](r_PG_DEFAULT_ACL.md) 系统目录表。

有关权限的更多信息，请参阅 [GRANT](r_GRANT.md)。

## 所需的权限
<a name="r_ALTER_DEFAULT_PRIVILEGES-privileges"></a>

以下是 ALTER DEFAULT PRIVILEGES 所需的权限：
+ Superuser
+ 具有 ALTER DEFAULT PRIVILEGES 权限的用户
+ 更改自己的默认访问权限的用户
+ 为其具有访问权限的 Schema 设置权限的用户

## 语法
<a name="r_ALTER_DEFAULT_PRIVILEGES-synopsis"></a>

```
ALTER DEFAULT PRIVILEGES
    [ FOR USER target_user [, ...] ]
    [ IN SCHEMA schema_name [, ...] ]
    grant_or_revoke_clause

where grant_or_revoke_clause is one of:

GRANT { { SELECT | INSERT | UPDATE | DELETE | DROP | REFERENCES | TRUNCATE } [,...] | ALL [ PRIVILEGES ] }
	ON TABLES
	TO { user_name [ WITH GRANT OPTION ] | ROLE role_name | GROUP group_name | PUBLIC } [, ...]

GRANT { EXECUTE | ALL [ PRIVILEGES ] }
	ON FUNCTIONS
	TO { user_name [ WITH GRANT OPTION ] |  ROLE role_name | GROUP group_name | PUBLIC } [, ...]

GRANT { EXECUTE | ALL [ PRIVILEGES ] }
	ON PROCEDURES
	TO { user_name [ WITH GRANT OPTION ] |  ROLE role_name | GROUP group_name | PUBLIC } [, ...]

REVOKE [ GRANT OPTION FOR ] { { SELECT | INSERT | UPDATE | DELETE | REFERENCES | TRUNCATE } [,...] | ALL [ PRIVILEGES ] }
	ON TABLES
	FROM user_name [, ...] [ RESTRICT ]

REVOKE  { { SELECT | INSERT | UPDATE | DELETE | REFERENCES | TRUNCATE } [,...] | ALL [ PRIVILEGES ] }
	ON TABLES
	FROM { ROLE role_name | GROUP group_name | PUBLIC } [, ...] [ RESTRICT ]

REVOKE [ GRANT OPTION FOR ] { EXECUTE | ALL [ PRIVILEGES ] }
	ON FUNCTIONS
	FROM user_name [, ...] [ RESTRICT ]

REVOKE { EXECUTE | ALL [ PRIVILEGES ] }
	ON FUNCTIONS
	FROM { ROLE role_name | GROUP group_name | PUBLIC } [, ...] [ RESTRICT ]

REVOKE [ GRANT OPTION FOR ] { EXECUTE | ALL [ PRIVILEGES ] }
	ON PROCEDURES
	FROM user_name [, ...] [ RESTRICT ]

REVOKE { EXECUTE | ALL [ PRIVILEGES ] }
	ON PROCEDURES
	FROM { ROLE role_name | GROUP group_name | PUBLIC } [, ...] [ RESTRICT ]
```

## 参数
<a name="r_ALTER_DEFAULT_PRIVILEGES-parameters"></a>

FOR USER *target\$1user*  <a name="default-for-user"></a>
可选。为其定义默认权限的用户的名称。只有超级用户能够为其他用户指定默认权限。默认值为当前用户。

IN SCHEMA *schema\$1name*   <a name="default-in-schema"></a>
可选。如果出现 IN SCHEMA 子句，则指定默认权限将应用于在指定 *schema\$1name* 中创建的新对象。在这种情况下，作为 ALTER DEFAULT PRIVILEGES 目标的用户或用户组必须对指定 schema 拥有 CREATE 权限。特定于某个 schema 的默认权限将添加到现有的全局默认权限中。默认情况下，默认权限全局应用于整个数据库。

GRANT   <a name="default-grant"></a>
针对指定用户创建的所有新表和视图、函数或存储过程，向指定的用户或组授予的权限集。与使用 [GRANT](r_GRANT.md) 命令一样，您可以使用 GRANT 子句来设置相同的权限和选项。

WITH GRANT OPTION   <a name="default-grant-option"></a>
一个子句，指示接收权限的用户又可以将相同权限授予其他用户。您无法将 WITH GRANT OPTION 授予组或 PUBLIC。

TO *user\$1name* \$1 ROLE *role\$1name* \$1 GROUP *group\$1name*   <a name="default-to"></a>
将指定的默认权限应用于的用户、角色或用户组的名称。

REVOKE   <a name="default-revoke"></a>
针对指定用户创建的所有新表、函数或存储过程，从指定的用户或组撤销权限集。与使用 [REVOKE](r_REVOKE.md) 命令一样，您可以使用 REVOKE 子句来设置相同的权限和选项。

GRANT OPTION FOR  <a name="default-revoke-option"></a>
 一个子句，仅撤消将指定的权限授予其他用户的选项，而不撤消权限本身。您无法从组或 PUBLIC 撤消 GRANT OPTION。

FROM *user\$1name* \$1 ROLE *role\$1name* \$1 GROUP *group\$1name*  <a name="default-from"></a>
默认情况下从其撤消指定权限的用户、角色或用户组的名称。

RESTRICT   <a name="default-restrict"></a>
RESTRICT 选项仅会撤消用户直接授予的权限。这是默认值。

## 示例
<a name="r_ALTER_DEFAULT_PRIVILEGES-examples"></a>

假设您希望允许用户组 `report_readers` 中的所有用户查看用户 `report_admin` 创建的所有表和视图。在这种情况下，以超级用户身份执行以下命令。

```
alter default privileges for user report_admin grant select on tables to group report_readers; 
```

在以下示例中，第一个命令授予对您创建的所有新表的 SELECT 权限。无论何时创建新视图，都必须显式授予对该视图的权限，或者再次运行 `alter default privileges` 命令。

```
alter default privileges grant select on tables to public; 
```

以下示例针对您在 `sales_admin` schema 中创建的所有新表和视图，将 INSERT 权限授予 `sales` 用户组。

```
alter default privileges in schema sales grant insert on tables to group sales_admin; 
```

以下示例撤消上述示例中 ALTER DEFAULT PRIVILEGES 命令的执行效果。

```
alter default privileges in schema sales revoke insert on tables from group sales_admin;
```

默认情况下，PUBLIC 用户组对所有新的用户定义的函数具有执行权限。要撤消对您的新函数的 `public` 执行权限，然后只将执行权限授予 `dev_test` 用户组，请运行以下命令。

```
alter default privileges revoke execute on functions from public;
alter default privileges grant execute on functions to group dev_test;
```

# ALTER EXTERNAL SCHEMA
<a name="r_ALTER_EXTERNAL_SCHEMA"></a>

更改当前数据库中的现有外部架构。只有架构拥有者、超级用户或对架构具有 ALTER 权限的用户才能更改架构。只能更改从 DATA CATALOG、KAFKA 或 MSK 创建的外部架构。

此 schema 的所有者为 CREATE EXTERNAL SCHEMA 命令的发布者。要移交外部 schema 的所有权，请使用 ALTER SCHEMA 更改所有者。要为其他用户或用户组授予对架构的访问权限，请使用 GRANT 命令。

您无法针对外部表的权限使用 GRANT 或 REVOKE 命令。相反，您可以授予或撤销对外部 schema 的权限。

有关更多信息，请参阅下列内容：
+ [ALTER SCHEMA](r_ALTER_SCHEMA.md)
+ [GRANT](r_GRANT.md)
+ [REVOKE](r_REVOKE.md)
+ [CREATE EXTERNAL SCHEMA](r_CREATE_EXTERNAL_SCHEMA.md)
+ [为现有外部架构启用 mTLS 身份验证](materialized-view-streaming-ingestion-mtls.md#materialized-view-streaming-ingestion-mtls-alter)

要查看外部架构的详细信息，请查询 SVV\$1EXTERNAL\$1SCHEMAS 系统视图。有关更多信息，请参阅 [SVV\$1EXTERNAL\$1SCHEMAS](r_SVV_EXTERNAL_SCHEMAS.md)。

## 语法
<a name="r_ALTER_EXTERNAL_SCHEMA-synopsis"></a>

```
ALTER EXTERNAL SCHEMA schema_name
[ IAM_ROLE [ default | 'SESSION' | 'arn:aws:iam::<account-id>:role/<role-name>' ] ]
[ AUTHENTICATION [ none | iam | mtls] ]
[ AUTHENTICATION_ARN 'acm-certificate-arn' | SECRET_ARN 'asm-secret-arn' ]
[ URI 'Kafka bootstrap URL' ]
```

如果您有一个用于流式摄取的现有外部架构，并且想要实现双向 TLS 进行身份验证，则可以运行如下命令，该命令在 ACM 中指定 mTLS 身份验证和 ACM 证书 ARN。

```
ALTER EXTERNAL SCHEMA schema_name 
AUTHENTICATION mtls
AUTHENTICATION_ARN 'arn:aws:acm:us-east-1:444455556666:certificate/certificate_ID';
```

或者，您可以参考 Secrets Manager 中的密钥 ARN 来修改 mTLS 身份验证。

```
ALTER EXTERNAL SCHEMA schema_name 
AUTHENTICATION mtls
SECRET_ARN 'arn:aws:secretsmanager:us-east-1:012345678910:secret:myMTLSSecret';
```

以下示例显示了如何修改 ALTER EXTERNAL SCHEMA 的 URI：

```
ALTER EXTERNAL SCHEMA schema_name  
URI 'lkc-ghidef-67890.centralus.azure.glb.confluent.cloud:9092';
```

以下示例显示了如何修改 ALTER EXTERNAL SCHEMA 的 IAM 角色：

```
ALTER EXTERNAL SCHEMA schema_name  
IAM_ROLE 'arn:aws:iam::012345678901:role/testrole';
```

## 参数
<a name="r_ALTER_EXTERNAL_SCHEMA-parameters"></a>

 IAM\$1ROLE[ default \$1 'SESSION' \$1 'arn:aws:iam::<AWS account-id>:role/<role-name>' ]   
使用 `default` 关键字让 Amazon Redshift 使用设置为默认值的 IAM 角色。  
如果您使用联合身份连接到 Amazon Redshift 集群并访问使用此命令创建的外部架构中的表，则使用 `'SESSION'`。  
有关更多信息，请参阅 [CREATE EXTERNAL SCHEMA](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_SCHEMA.html)。

AUTHENTICATION  
为流式摄取定义的身份验证类型。具有身份验证类型的流式摄取使用 Apache Kafka、Confluent Cloud 和 Amazon Managed Streaming for Apache Kafka。有关更多信息，请参阅 [CREATE EXTERNAL SCHEMA](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_SCHEMA.html)。

AUTHENTICATION\$1ARN  
Amazon Redshift 用于通过 Apache Kafka、Confluent Cloud 或 Amazon Managed Streaming for Apache Kafka（Amazon MSK）进行 mtls 身份验证的 AWS Certificate Manager 证书的 ARN。当您选择已签发证书时，ARN 就会出现在 ACM 控制台中。

SECRET\$1ARN  
使用 AWS Secrets Manager 创建的受支持密钥的 Amazon 资源名称（ARN）。有关如何创建和检索密钥的 ARN 的信息，请参阅《AWS Secrets Manager User Guide》**中的 [Manage secrets with AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/manage_create-basic-secret.html)，以及[在 Amazon Redshift 中检索密钥的 Amazon 资源名称（ARN）](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-secrets-manager-integration-retrieving-secret.html)。

URI  
Apache Kafka、Confluent Cloud 或 Amazon Managed Streaming for Apache Kafka（Amazon MSK）集群的引导 URL。端点必须可以从 Amazon Redshift 集群进行访问（路由）。有关更多信息，请参阅 [CREATE EXTERNAL SCHEMA](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_SCHEMA.html)。

# ALTER EXTERNAL VIEW
<a name="r_ALTER_EXTERNAL_VIEW"></a>

使用 ALTER EXTERNAL VIEW 命令更新您的外部视图。根据您使用的参数，也可以引用此视图的其他 SQL 引擎（例如 Amazon Athena 和 Amazon EMR Spark）可能会受到影响。有关 Data Catalog 视图的更多信息，请参阅 [AWS Glue Data Catalog 视图](https://docs.aws.amazon.com/redshift/latest/dg/data-catalog-views-overview.html)。

## 语法
<a name="r_ALTER_EXTERNAL_VIEW-synopsis"></a>

```
ALTER EXTERNAL VIEW schema_name.view_name
{catalog_name.schema_name.view_name | awsdatacatalog.dbname.view_name | external_schema_name.view_name}
[FORCE] { AS (query_definition) | REMOVE DEFINITION }
```

## 参数
<a name="r_ALTER_EXTERNAL_VIEW-parameters"></a>

 *schema\$1name.view\$1name*   
附加到 AWS Glue 数据库的架构，后面是视图的名称。

catalog\$1name.schema\$1name.view\$1name \$1 awsdatacatalog.dbname.view\$1name \$1 external\$1schema\$1name.view\$1name  
更改视图时要使用的架构符号。可以指定使用您创建的 Glue 数据库 AWS Glue Data Catalog 或您创建的外部架构。有关更多信息，请参阅 [CREATE DATABASE](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_DATABASE.html) 和 [CREATE EXTERNAL SCHEMA](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_SCHEMA.html)。

FORCE  
即使表中引用的对象与其他 SQL 引擎不一致，AWS Lake Formation 是否仍应更新视图的定义。如果 Lake Formation 更新了视图，其他 SQL 引擎就会认为该视图是过时的，直到这些引擎也更新为止。

 *AS query\$1definition*   
Amazon Redshift 为更改视图而运行的 SQL 查询的定义。

REMOVE DEFINITION  
是否删除并重新创建视图。必须删除并重新创建视图才能将其标记为 `PROTECTED`。

## 示例
<a name="r_ALTER_EXTERNAL_VIEW-examples"></a>

以下示例更改了名为 sample\$1schema.glue\$1data\$1catalog\$1view 的 Data Catalog 视图。

```
ALTER EXTERNAL VIEW sample_schema.glue_data_catalog_view
FORCE
REMOVE DEFINITION
```

# ALTER FUNCTION
<a name="r_ALTER_FUNCTION"></a>

重命名函数或者更改拥有者。函数名称和数据类型均为必需项。只有拥有者或超级用户可以重命名函数。只有超级用户可以更改函数的拥有者。

## 语法
<a name="r_ALTER_FUNCTION-synopsis"></a>

```
ALTER FUNCTION function_name ( { [ py_arg_name py_arg_data_type | sql_arg_data_type } [ , ... ] ] )
     RENAME TO new_name
```

```
ALTER FUNCTION function_name ( { [ py_arg_name py_arg_data_type | sql_arg_data_type } [ , ... ] ] )
     OWNER TO { new_owner | CURRENT_USER | SESSION_USER }
```

## 参数
<a name="r_ALTER_FUNCTION-parameters"></a>

 *function\$1name*   
要更改的函数的名称。指定当前搜索路径中函数的名称，或者通过格式 `schema_name.function_name` 使用特定架构。

*py\$1arg\$1name py\$1arg\$1data\$1type \$1 sql\$1arg\$1data\$1type*   
可选。Python 用户定义函数的输入参数名称和数据类型的列表，或 SQL 用户定义函数的输入参数数据类型的列表。

 *new\$1name*   
用户定义函数的新名称。

*new\$1owner* \$1 CURRENT\$1USER \$1 SESSION\$1USER  
用户定义函数的新拥有者。

## 示例
<a name="r_ALTER_FUNCTION-examples"></a>

以下示例将函数的名称从 `first_quarter_revenue` 更改为 `quarterly_revenue`。

```
ALTER FUNCTION first_quarter_revenue(bigint, numeric, int) 
         RENAME TO quarterly_revenue;
```

以下示例将 `quarterly_revenue` 函数的拥有者更改为 `etl_user`。

```
ALTER FUNCTION quarterly_revenue(bigint, numeric) OWNER TO etl_user;
```

# ALTER GROUP
<a name="r_ALTER_GROUP"></a>

更改用户组。使用此命令可以将用户添加到组、从组中删除用户或重命名组。

## 语法
<a name="r_ALTER_GROUP-synopsis"></a>

```
ALTER GROUP group_name
{
ADD USER username [, ... ] |
DROP USER username [, ... ] |
RENAME TO new_name
}
```

## 参数
<a name="r_ALTER_GROUP-parameters"></a>

 *group\$1name*   
要修改的用户组的名称。

ADD   
将用户添加到用户组。

DROP   
从用户组中删除用户。

 *username*   
要添加到组或从组中删除的用户的名称。

RENAME TO   
重命名用户组。以两个下划线开头的组名保留供 Amazon Redshift 内部使用。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。

 *new\$1name*   
用户组的新名称。

## 示例
<a name="r_ALTER_GROUP-examples"></a>

以下示例将名为 DWUSER 的用户添加到 ADMIN\$1GROUP 组。

```
ALTER GROUP admin_group
ADD USER dwuser;
```

以下示例将组 ADMIN\$1GROUP 重命名为 ADMINISTRATORS。

```
ALTER GROUP admin_group
RENAME TO administrators;
```

以下示例将两个用户添加到组 ADMIN\$1GROUP。

```
ALTER GROUP admin_group
ADD USER u1, u2;
```

以下示例从 ADMIN\$1GROUP 组删除两个用户。

```
ALTER GROUP admin_group
DROP USER u1, u2;
```

# ALTER IDENTITY PROVIDER
<a name="r_ALTER_IDENTITY_PROVIDER"></a>

更改身份提供者以分配新的参数和值。运行此命令时，先前设置的所有参数值都将在分配新值之前删除。只有超级用户可以更改身份提供者。

## 语法
<a name="r_ALTER_IDENTITY_PROVIDER-synopsis"></a>

```
ALTER IDENTITY PROVIDER identity_provider_name
[PARAMETERS parameter_string]
[NAMESPACE namespace]
[IAM_ROLE iam_role]
[AUTO_CREATE_ROLES
    [ TRUE [ { INCLUDE | EXCLUDE } GROUPS LIKE filter_pattern] |
      FALSE
    ]
[DISABLE | ENABLE]
```

## 参数
<a name="r_ALTER_IDENTITY_PROVIDER-parameters"></a>

 *identity\$1provider\$1name*   
新身份提供者的名称。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。

 *parameter\$1string*   
一个包含格式正确的 JSON 对象的字符串，其中包含特定身份提供者所需的参数和值。

 *命名空间*   
组织命名空间。

 *iam\$1role*   
提供连接到 IAM Identity Center 的权限的 IAM 角色。仅当身份提供者类型为 AWSIDC 时，此参数才适用。

 *auto\$1create\$1roles*   
启用或禁用自动创建角色特征。如果该值为 TRUE，则 Amazon Redshift 启用自动创建角色功能。如果该值为 FALSE，则 Amazon Redshift 禁用自动创建角色功能。如果未指定此参数的值，Amazon Redshift 将使用以下逻辑确定该值：  
+  如果提供了 `AUTO_CREATE_ROLES` 但未指定值，则该值设置为 TRUE。
+  如果未提供 `AUTO_CREATE_ROLES` 且身份提供者为 AWSIDC，则该值设置为 FALSE。
+  如果未提供 `AUTO_CREATE_ROLES` 且身份提供者为 Azure，则该值设置为 TRUE。
要包括组，请指定 `INCLUDE`。默认值为空，这意味着如果 `AUTO_CREATE_ROLES` 为开启，则包括所有组。  
要排除组，请指定 `EXCLUDE`。默认值为空，这意味着如果 `AUTO_CREATE_ROLES` 为开启，则不排除任何组。

 *filter\$1pattern*   
一个有效的 UTF-8 字符表达式，具有与组名称匹配的模式。LIKE 选项执行区分大小写的匹配，支持以下模式匹配元字符：      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_ALTER_IDENTITY_PROVIDER.html)
如果 *filter\$1pattern* 不包含元字符，则模式仅表示字符串本身；在此情况下，LIKE 的行为与等于运算符相同。  
*filter\$1pattern* 支持以下字符：  
+  大写和小写字母字符（A-Z 和 a-z） 
+  数字（0-9） 
+  以下特殊字符：

  ```
  _ % ^ * + ? { } , $
  ```

 *DISABLE 或 ENABLE*   
开启或关闭身份提供者。默认值为 ENABLE。

## 示例
<a name="r_ALTER_IDENTITY_PROVIDER-examples"></a>

以下示例更改名为 *oauth\$1standard* 的身份提供者。它特别适用于 Microsoft Azure AD 作为身份提供者的情况。

```
ALTER IDENTITY PROVIDER oauth_standard
PARAMETERS '{"issuer":"https://sts.windows.net/2sdfdsf-d475-420d-b5ac-667adad7c702/",
"client_id":"87f4aa26-78b7-410e-bf29-57b39929ef9a",
"client_secret":"BUAH~ewrqewrqwerUUY^%tHe1oNZShoiU7",
"audience":["https://analysis.windows.net/powerbi/connector/AmazonRedshift"]
}'
```

以下示例显示了如何设置身份提供者命名空间。这可能适用于 Microsoft Azure AD（如果它遵循与上一个示例类似的语句），也可能适用于其它身份提供者。如果您通过托管应用程序设置了连接，则它也可能适用于将现有的 Amazon Redshift 预调配集群或 Amazon Redshift Serverless 工作组连接到 IAM Identity Center 的情况。

```
ALTER IDENTITY PROVIDER "my-redshift-idc-application"
NAMESPACE 'MYCO';
```

以下示例设置了 IAM 角色，并适用于配置 Redshift 与 IAM Identity Center 集成的使用案例。

```
ALTER IDENTITY PROVIDER "my-redshift-idc-application"
IAM_ROLE 'arn:aws:iam::123456789012:role/myadministratorrole';
```

有关设置从 Redshift 到 IAM Identity Center 的连接的更多信息，请参阅[将 Redshift 与 IAM Identity Center 连接，为用户提供单点登录体验](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-idp-connect.html)。

**禁用身份提供者**

以下示例语句显示了如何禁用身份提供者。禁用身份提供者后，身份提供者中的联合用户将无法登录集群，直至再次启用它。

```
ALTER IDENTITY PROVIDER "redshift-idc-app" DISABLE;
```

# ALTER MASKING POLICY
<a name="r_ALTER_MASKING_POLICY"></a>

更改现有的动态数据掩蔽政策。有关动态数据掩蔽的更多信息，请参阅 [动态数据掩蔽](t_ddm.md)。

超级用户和具有 sys:secadmin 角色的用户或角色可以更改掩蔽政策。

## 语法
<a name="r_ALTER_MASKING_POLICY-synopsis"></a>

```
ALTER MASKING POLICY
{ policy_name | database_name.policy_name }
USING (masking_expression);
```

## 参数
<a name="r_ALTER_MASKING_POLICY-parameters"></a>

*policy\$1name*   
 屏蔽策略的名称。此名称必须是数据库中已存在的掩蔽政策的名称。

database\$1name  
从其中创建策略的数据库的名称。该数据库可以是连接的数据库，也可以是支持 Amazon Redshift 联合身份验证权限的数据库。

*masking\$1expression*  
用于转换目标列的 SQL 表达式。可以使用诸如字符串操作函数之类的数据操作函数来编写该表达式，也可以与使用 SQL、Python 或 AWS Lambda 编写的用户定义函数结合使用。  
 表达式必须与原始表达式的输入列和数据类型相匹配。例如，如果原始掩蔽政策的输入列是 `sample_1 FLOAT` 和 `sample_2 VARCHAR(10)`，则您将无法更改掩蔽政策来使用第三列，也无法使该政策采用一个浮点数和一个布尔值。如果您使用常量作为掩蔽表达式，则必须将其显式转换为与输入类型匹配的类型。  
 您必须对在屏蔽表达式中使用的任何用户定义函数具有 USAGE 权限。

有关在 Amazon Redshift 联合身份验证权限目录上使用 ALTER MASKING POLICY 的信息，请参阅[使用 Amazon Redshift 联合身份验证权限管理访问控制](https://docs.aws.amazon.com/redshift/latest/dg/federated-permissions-managing-access.html)。

# ALTER MATERIALIZED VIEW
<a name="r_ALTER_MATERIALIZED_VIEW"></a>

更改实体化视图的属性。

## 语法
<a name="r_ALTER_MATERIALIZED_VIEW-synopsis"></a>

```
ALTER MATERIALIZED VIEW mv_name
{
AUTO REFRESH { YES | NO } 
| ALTER DISTKEY column_name
| ALTER DISTSTYLE ALL
| ALTER DISTSTYLE EVEN
| ALTER DISTSTYLE KEY DISTKEY column_name
| ALTER DISTSTYLE AUTO
| ALTER [COMPOUND] SORTKEY ( column_name [,...] )
| ALTER SORTKEY AUTO
| ALTER SORTKEY NONE
| ROW LEVEL SECURITY { ON | OFF } [ CONJUNCTION TYPE { AND | OR } ] [FOR DATASHARES]
};
```

## 参数
<a name="r_ALTER_MATERIALIZED_VIEW-parameters"></a>

*mv\$1name*  
要更改的实体化视图的名称。

AUTO REFRESH \$1 YES \$1 NO \$1  
开启或关闭实体化视图的自动刷新的子句。有关自动刷新实体化视图的更多信息，请参阅[刷新实体化视图](materialized-view-refresh.md)。

ALTER DISTSTYLE ALL  
用于将关系的现有分配方式更改为 `ALL` 的子句。请考虑以下事项：  
+ 不能对同一个关系并发运行 ALTER DISTSTYLE、ALTER SORTKEY 和 VACUUM。
  + 如果 VACUUM 当前正在运行，则运行 ALTER DISTSTYLE ALL 将返回错误。
  + 如果 ALTER DISTSTYLE ALL 正在运行，则不对关系启动后台 vacuum。
+ 对于具有交错排序键和临时表的关系，不支持 ALTER DISTSTYLE ALL 命令。
+ 如果分配方式以前被定义为 AUTO，则关系不再是自动表优化的候选项。
有关 DISTSTYLE ALL 的更多信息，请转至 [CREATE MATERIALIZED VIEW](materialized-view-create-sql-command.md)。

ALTER DISTSTYLE EVEN  
用于将关系的现有分配方式更改为 `EVEN` 的子句。请考虑以下事项：  
+ 不能对同一个关系并发运行 ALTER DISTSYTLE、ALTER SORTKEY 和 VACUUM。
  + 如果 VACUUM 当前正在运行，则运行 ALTER DISTSTYLE EVEN 将返回错误。
  + 如果 ALTER DISTSTYLE EVEN 正在运行，则不对关系启动后台 Vacuum。
+ 对于具有交错排序键和临时表的关系，不支持 ALTER DISTSTYLE EVEN 命令。
+ 如果分配方式以前被定义为 AUTO，则关系不再是自动表优化的候选项。
有关 DISTSTYLE EVEN 的更多信息，请转至 [CREATE MATERIALIZED VIEW](materialized-view-create-sql-command.md)。

ALTER DISTKEY *column\$1name* 或 ALTER DISTSTYLE KEY DISTKEY *column\$1name*  
一个子句，可更改用作关系的分配键的列。请考虑以下事项：  
+ 不能对同一个关系并发运行 VACUUM 和 ALTER DISTKEY。
  + 如果 VACUUM 已经运行，则 ALTER DISTKEY 返回错误。
  + 如果 ALTER DISTKEY 正在运行，则不对关系启动后台 Vacuum。
  + 如果 ALTER DISTKEY 正在运行，则前台 vacuum 会返回错误。
+ 您一次只能对一个关系运行一个 ALTER DISTKEY 命令。
+ 具有交错排序键的关系不支持 ALTER DISTKEY 命令。
+ 如果分配方式以前被定义为 AUTO，则关系不再是自动表优化的候选项。
指定 DISTSTYLE KEY 时，按 DISTKEY 列中的值分配数据。有关 DISTSTYLE 的更多信息，请转至 [CREATE MATERIALIZED VIEW](materialized-view-create-sql-command.md)。

ALTER DISTSTYLE AUTO  
用于将关系的现有分配方式更改为 AUTO 的子句。  
将分配方式更改为 AUTO 时，关系的分配方式设置为以下内容：  
+ 带有 DISTSTYLE ALL 的小型关系被转换为 AUTO(ALL)。
+ 带有 DISTSTYLE EVEN 的小型关系被转换为 AUTO(ALL)。
+ 带有 DISTSTYLE KEY 的小型关系被转换为 AUTO(ALL)。
+ 带有 DISTSTYLE ALL 的大型关系被转换为 AUTO(EVEN)。
+ 带有 DISTSTYLE EVEN 的大型关系被转换为 AUTO(EVEN)。
+ 带有 DISTSTYLE KEY 的大型关系被转换为 AUTO(KEY)，且保留 DISTKEY。在这种情况下，Amazon Redshift 不对关系进行任何更改。
如果 Amazon Redshift 确定新的分配方式或键将提高查询的性能，那么 Amazon Redshift 将来可能会更改关系的分配方式或键。例如，Amazon Redshift 可能会将 DISTSTYLE 为 AUTO(KEY) 的关系转换为 AUTO(EVEN)，反之亦然。有关分发键被更改时的行为的更多信息（包括数据重新分发和锁定），请转至 [Amazon Redshift Advisor 建议](https://docs.aws.amazon.com/redshift/latest/dg/advisor-recommendations.html#alter-diststyle-distkey-recommendation)。  
有关 DISTSTYLE AUTO 的更多信息，请转至 [CREATE MATERIALIZED VIEW](materialized-view-create-sql-command.md)。  
要查看关系的分配方式，请查询 SVV\$1TABLE\$1INFO 系统目录视图。有关更多信息，请转至 [SVV\$1TABLE\$1INFO](r_SVV_TABLE_INFO.md)。要查看 Amazon Redshift Advisor 对关系的建议，请查询 SVV\$1ALTER\$1TABLE\$1RECOMMENDATIONS 系统目录视图。有关更多信息，请转至 [SVV\$1ALTER\$1TABLE\$1RECOMMENDATIONS](r_SVV_ALTER_TABLE_RECOMMENDATIONS.md)。要查看 Amazon Redshift 所采取的操作，请查询 SVL\$1AUTO\$1WORKER\$1ACTION 系统目录视图。有关更多信息，请转至 [SVL\$1AUTO\$1WORKER\$1ACTION](r_SVL_AUTO_WORKER_ACTION.md)。

ALTER [COMPOUND] SORTKEY ( *column\$1name* [,...] )  
一个旨在更改或添加用于关系的排序键的子句。临时表不支持 ALTER SORTKEY。  
当您更改排序键时，新排序键或原始排序键中列的压缩编码可能会更改。如果没有为关系显式定义编码，则 Amazon Redshift 按如下方式自动分配压缩编码：  
+ 为定义为排序键的列分配 RAW 压缩。
+ 为定义为 BOOLEAN、REAL 或 DOUBLE PRECISION 数据类型的列分配 RAW 压缩。
+ 定义为 SMALLINT、INTEGER、BIGINT、DECIMAL、DATE、TIME、TIMETZT、IMESTAMP 或 TIMESTAMPTZ 的列分配了 AZ64 压缩。
+ 定义为 CHAR 或 VARCHAR 的列分配了 LZO 压缩。
请考虑以下事项：  
+ 最多可以为每个关系的排序键定义 400 列。
+ 您可以将交错排序键更改为复合排序键或没有排序键。但是，您不能将复合排序键更改为交错排序键。
+ 如果排序键以前被定义为 AUTO，则关系不再是自动表优化的候选项。
+ Amazon Redshift 建议对定义为排序键的列使用 RAW 编码（不压缩）。当您更改列以将其选择为排序键时，列的压缩将更改为 RAW 压缩（无压缩）。这将增加关系所需的存储空间量。关系大小的增加程度取决于特定的关系定义和关系内容。有关压缩的更多信息，请转至[压缩编码](c_Compression_encodings.md)。
将数据加载到关系中时，将按照排序键的顺序加载数据。更改排序键时，Amazon Redshift 对数据重新排序。有关 SORTKEY 的更多信息，请转至 [CREATE MATERIALIZED VIEW](materialized-view-create-sql-command.md)。

ALTER SORTKEY AUTO  
一个用于将目标关系的排序键更改为或添加到 AUTO 的子句。临时表不支持 ALTER SORTKEY AUTO。  
当您将排序键更改为 AUTO 时，Amazon Redshift 会保留关系的现有排序键。  
如果 Amazon Redshift 确定新的排序键将提高查询的性能，那么 Amazon Redshift 将来可能会更改关系的排序键。  
有关 SORTKEY AUTO 的更多信息，请转至 [CREATE MATERIALIZED VIEW](materialized-view-create-sql-command.md)。  
要查看关系的排序键，请查询 SVV\$1TABLE\$1INFO 系统目录视图。有关更多信息，请转至 [SVV\$1TABLE\$1INFO](r_SVV_TABLE_INFO.md)。要查看 Amazon Redshift Advisor 对关系的建议，请查询 SVV\$1ALTER\$1TABLE\$1RECOMMENDATIONS 系统目录视图。有关更多信息，请转至 [SVV\$1ALTER\$1TABLE\$1RECOMMENDATIONS](r_SVV_ALTER_TABLE_RECOMMENDATIONS.md)。要查看 Amazon Redshift 所采取的操作，请查询 SVL\$1AUTO\$1WORKER\$1ACTION 系统目录视图。有关更多信息，请转至 [SVL\$1AUTO\$1WORKER\$1ACTION](r_SVL_AUTO_WORKER_ACTION.md)。

ALTER SORTKEY NONE  
用于移除目标关系的排序键的子句。  
如果排序键以前被定义为 AUTO，则关系不再是自动表优化的候选项。

ROW LEVEL SECURITY \$1 ON \$1 OFF \$1 [ CONJUNCTION TYPE \$1 AND \$1 OR \$1 ] [ FOR DATASHARES ]  
一个对关系开启或关闭行级安全性的子句。  
在为关系开启行级安全性后，您只能读取行级安全策略允许您访问的行。如果没有策略向您授予对关系的访问权限，您将看不到关系中的任何行。只有超级用户和拥有 `sys:secadmin` 角色的用户或角色才能设置 ROW LEVEL SECURITY 子句。有关更多信息，请参阅 [行级别安全性](t_rls.md)。  
+ [ CONJUNCTION TYPE \$1 AND \$1 OR \$1 ] 

  一个允许您为关系选择行级安全策略的联接类型的子句。将多个行级安全策略附加到关系时，可以将这些策略与 AND 或 OR 子句合并。默认情况下，Amazon Redshift 将 RLS 策略与 AND 子句合并。具有 `sys:secadmin` 角色的超级用户、用户或角色可以使用此子句为关系定义行级安全策略的联接类型。有关更多信息，请参阅 [为每个用户组合多个策略](t_rls_combine_policies.md)。
+ FOR DATASHARES

   一个子句，用于确定是否可以通过数据共享访问受 RLS 保护的关系。默认情况下，无法通过数据共享访问受 RLS 保护的关系。使用此子句运行的 ALTER MATERIALIZED VIEW ROW LEVEL SECURITY 命令只会影响关系的数据共享可访问性属性。ROW LEVEL SECURITY 属性未更改。

   如果您允许通过数据共享访问受 RLS 保护的关系，则该关系在使用者端数据共享数据库中没有行级安全性。该关系在生产者端保留其 RLS 属性。

## 示例
<a name="r_ALTER_MATERIALIZED_VIEW-examples"></a>

以下示例启用要自动刷新的 `tickets_mv` 实体化视图。

```
ALTER MATERIALIZED VIEW tickets_mv AUTO REFRESH YES
```

# ALTER MATERIALIZED VIEW 的 DISTSTYLE 和 SORTKEY 示例
<a name="r_ALTER_MATERIALIZED_VIEW-DISTSTYLE-SORTKEY-examples"></a>

本主题中的示例向您展示了如何使用 ALTER MATERIAD VIEW 对 DISTYLE 和 SORTKEY 进行更改。

以下示例查询显示了如何使用示例基表更改 DISTSTYLE KEY DISTKEY 列：

```
CREATE TABLE base_inventory(
  inv_date_sk int4 NOT NULL,
  inv_item_sk int4 NOT NULL,
  inv_warehouse_sk int4 NOT NULL,
  inv_quantity_on_hand int4
);

INSERT INTO base_inventory VALUES(1,1,1,1);

CREATE materialized VIEW inventory diststyle even AS SELECT * FROM base_inventory;
SELECT "table", diststyle FROM svv_table_info WHERE "table" = 'inventory';

ALTER materialized VIEW inventory ALTER diststyle KEY distkey inv_warehouse_sk;
SELECT "table", diststyle FROM svv_table_info WHERE "table" = 'inventory';

ALTER materialized VIEW inventory ALTER distkey inv_item_sk;
SELECT "table", diststyle FROM svv_table_info WHERE "table" = 'inventory';

DROP TABLE base_inventory CASCADE;
```

将实体化视图更改为 DISTSTYLE ALL：

```
CREATE TABLE base_inventory(
  inv_date_sk int4 NOT NULL,
  inv_item_sk int4 NOT NULL,
  inv_warehouse_sk int4 NOT NULL,
  inv_quantity_on_hand int4
);

INSERT INTO base_inventory VALUES(1,1,1,1);

CREATE materialized VIEW inventory diststyle even AS SELECT * FROM base_inventory;
SELECT "table", diststyle FROM svv_table_info WHERE "table" = 'inventory';

ALTER MATERIALIZED VIEW inventory ALTER diststyle ALL;
SELECT "table", diststyle FROM svv_table_info WHERE "table" = 'inventory';

DROP TABLE base_inventory CASCADE;
```

以下命令显示了使用示例基表的 ALTER MATERIALIZED VIEW SORTKEY 示例：

```
CREATE TABLE base_inventory (c0 int, c1 int);

INSERT INTO base_inventory VALUES(1,1);

CREATE materialized VIEW inventory interleaved sortkey(c0, c1) AS SELECT * FROM base_inventory;
SELECT "table", sortkey1 FROM svv_table_info WHERE "table" = 'inventory';

ALTER materialized VIEW inventory ALTER sortkey(c0, c1);
SELECT "table", diststyle, sortkey_num FROM svv_table_info WHERE "table" = 'inventory';

ALTER materialized VIEW inventory ALTER sortkey NONE;
SELECT "table", diststyle, sortkey_num FROM svv_table_info WHERE "table" = 'inventory';

ALTER materialized VIEW inventory ALTER sortkey(c0);
SELECT "table", diststyle, sortkey_num FROM svv_table_info WHERE "table" = 'inventory';

DROP TABLE base_inventory CASCADE;
```

# ALTER RLS POLICY
<a name="r_ALTER_RLS_POLICY"></a>

更改表上现有的行级别安全性策略。

超级用户和具有 `sys:secadmin` 角色的用户或角色可以更改策略。

## 语法
<a name="r_ALTER_RLS_POLICY-synopsis"></a>

```
ALTER RLS POLICY
{ policy_name | database_name.policy_name }
USING ( using_predicate_exp );
```

## 参数
<a name="r_ALTER_RLS_POLICY-parameters"></a>

 *policy\$1name*   
策略的名称。

database\$1name  
从其中创建策略的数据库的名称。该数据库可以是连接的数据库，也可以是支持 Amazon Redshift 联合身份验证权限的数据库。

USING (* using\$1predicate\$1exp *)  
指定应用于查询的 WHERE 子句的筛选器。Amazon Redshift 会在查询级别的用户谓词之前应用策略谓词。例如，**current\$1user = ‘joe’ and price > 10** 限制 Joe 只能查看价格高于 10 美元的记录。  
该表达式可以访问在 CREATE RLS POLICY 语句的 WITH 子句中声明的变量，该语句用于创建名为 policy\$1name 的策略。

有关在 Amazon Redshift 联合身份验证权限目录上使用 ALTER RLS POLICY 的信息，请参阅[使用 Amazon Redshift 联合身份验证权限管理访问控制](https://docs.aws.amazon.com/redshift/latest/dg/federated-permissions-managing-access.html)。

## 示例
<a name="r_ALTER_RLS_POLICY-examples"></a>

以下示例介绍了更改 RLS 策略。

```
-- First create an RLS policy that limits access to rows where catgroup is 'concerts'.
CREATE RLS POLICY policy_concerts
WITH (catgroup VARCHAR(10))
USING (catgroup = 'concerts');

-- Then, alter the RLS policy to only show rows where catgroup is 'piano concerts'.
ALTER RLS POLICY policy_concerts
USING (catgroup = 'piano concerts');
```

# ALTER ROLE
<a name="r_ALTER_ROLE"></a>

重命名角色或者更改拥有者。有关 Amazon Redshift 系统定义的角色列表，请参阅[Amazon Redshift 系统定义的角色](r_roles-default.md)。

## 所需的权限
<a name="r_ALTER_ROLE-privileges"></a>

以下是 ALTER ROLE 所需的权限：
+ Superuser
+ 具有 ALTER ROLE 权限的用户

## 语法
<a name="r_ALTER_ROLE-synopsis"></a>

```
ALTER ROLE role [ WITH ]
  { { RENAME TO role } | { OWNER TO user_name } }[, ...]
  [ EXTERNALID TO external_id ]
```

## 参数
<a name="r_ALTER_ROLE-parameters"></a>

 *role*   
要更改的角色的名称。

RENAME TO  
角色的新名称。

OWNER TO *user\$1name*  
角色的新拥有者。

EXTERNALID TO *external\$1id*  
角色的新外部 ID，与身份提供者关联。有关更多信息，请参阅 [Amazon Redshift 的原生身份提供者 (IdP) 联合身份验证](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-native-idp.html)。

## 示例
<a name="r_ALTER_ROLE-examples"></a>

以下示例将角色的名称从 `sample_role1` 更改为 `sample_role2`。

```
ALTER ROLE sample_role1 RENAME TO sample_role2;
```

以下示例将更改角色的拥有者。

```
ALTER ROLE sample_role1 WITH OWNER TO user1
```

ALTER ROLE 的语法与以下 ALTER PROCEDURE 类似。

```
ALTER PROCEDURE first_quarter_revenue(bigint, numeric) RENAME TO quarterly_revenue;
```

以下示例将过程的拥有者更改为 `etl_user`。

```
ALTER PROCEDURE quarterly_revenue(bigint, numeric) OWNER TO etl_user;
```

以下示例使用与身份提供者关联的新外部 ID 更新了角色 `sample_role1`。

```
ALTER ROLE sample_role1 EXTERNALID TO "XYZ456";
```

# ALTER PROCEDURE
<a name="r_ALTER_PROCEDURE"></a>

重命名过程或者更改拥有者。需要过程名称和数据类型（或签名）。只有拥有者或超级用户可以重命名过程。只有超级用户可以更改过程的拥有者。

## 语法
<a name="r_ALTER_PROCEDURE-synopsis"></a>

```
ALTER PROCEDURE sp_name [ ( [ [ argname ] [ argmode ] argtype [, ...] ] ) ]
    RENAME TO new_name
```

```
ALTER PROCEDURE sp_name [ ( [ [ argname ] [ argmode ] argtype [, ...] ] ) ]
    OWNER TO { new_owner | CURRENT_USER | SESSION_USER }
```

## 参数
<a name="r_ALTER_PROCEDURE-parameters"></a>

 *sp\$1name*   
要变更的过程的名称。只指定当前搜索路径中过程的名称，或者通过格式 `schema_name.sp_procedure_name` 使用特定 schema。

*[argname] [argmode] argtype*   
参数名称、参数模式和数据类型的列表。只需要输入数据类型，这些数据类型用于标识存储过程。另外，您可以提供用于创建过程的完整签名，包括输入和输出参数及其模式。

 *new\$1name*   
存储过程的新名称。

*new\$1owner* \$1 CURRENT\$1USER \$1 SESSION\$1USER  
存储过程的新拥有者。

## 示例
<a name="r_ALTER_PROCEDURE-examples"></a>

以下示例将过程的名称从 `first_quarter_revenue` 更改为 `quarterly_revenue`。

```
ALTER PROCEDURE first_quarter_revenue(volume INOUT bigint, at_price IN numeric,
 result OUT int) RENAME TO quarterly_revenue;
```

此示例等效于以下内容：

```
ALTER PROCEDURE first_quarter_revenue(bigint, numeric) RENAME TO quarterly_revenue;
```

以下示例将过程的拥有者更改为 `etl_user`。

```
ALTER PROCEDURE quarterly_revenue(bigint, numeric) OWNER TO etl_user;
```

# ALTER SCHEMA
<a name="r_ALTER_SCHEMA"></a>

更改现有 schema 的定义。使用此命令可重命名 schema 或更改 schema 的所有者。例如，当您计划创建现有 schema 的新版本时，将现有 schema 重命名可保留该 schema 的备份副本。有关 schema 的更多信息，请参阅 [CREATE SCHEMA](r_CREATE_SCHEMA.md)。

要查看已配置的 schema 配额，请参阅[SVV\$1SCHEMA\$1QUOTA\$1STATE](r_SVV_SCHEMA_QUOTA_STATE.md)。

要查看已超出 schema 配额的记录，请参阅[STL\$1SCHEMA\$1QUOTA\$1VIOLATIONS](r_STL_SCHEMA_QUOTA_VIOLATIONS.md)。

## 所需的权限
<a name="r_ALTER_SCHEMA-privileges"></a>

以下是 ALTER SCHEMA 所需的权限：
+ Superuser
+ 具有 ALTER SCHEMA 权限的用户
+ Schema 拥有者

更改架构名称时，请注意，使用了旧名称的对象，例如存储过程或实体化视图，必须对其进行更新以使用新名称。

## 语法
<a name="r_ALTER_SCHEMA-synopsis"></a>

```
ALTER SCHEMA schema_name
{
RENAME TO new_name |
OWNER TO new_owner |
QUOTA { quota [MB | GB | TB] | UNLIMITED }
}
```

## 参数
<a name="r_ALTER_SCHEMA-parameters"></a>

 *schema\$1name*   
要修改的数据库 schema 的名称。

RENAME TO   
用于重命名 schema 的子句。

 *new\$1name*   
schema 的新名称。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。

OWNER TO   
用于更改 schema 所有者的子句。

 *new\$1owner*   
schema 的新所有者。

QUOTA   
指定的 schema 可以使用的最大磁盘空间量。此空间是指定 schema 下所有表的整体大小。Amazon Redshift 将选定值转换为 MB。如果您未指定值，则 GB 是默认的测量单位。  
有关配置 schema 配额的更多信息，请参阅[CREATE SCHEMA](r_CREATE_SCHEMA.md)。

## 示例
<a name="r_ALTER_SCHEMA-examples"></a>

以下示例将 SALES schema 重命名为 US\$1SALES。

```
alter schema sales
rename to us_sales;
```

以下示例将 US\$1SALES schema 的所有权授予用户 DWUSER。

```
alter schema us_sales
owner to dwuser;
```

以下示例将配额更改为 300 GB 并删除此配额。

```
alter schema us_sales QUOTA 300 GB;
alter schema us_sales QUOTA UNLIMITED;
```

# ALTER SYSTEM
<a name="r_ALTER_SYSTEM"></a>

更改 Amazon Redshift 集群或 Redshift Serverless 工作组的系统级配置选项。

## 所需的权限
<a name="r_ALTER_SYSTEM-privileges"></a>

以下用户类型之一可以运行 ALTER SYSTEM 命令：
+ Superuser
+ 管理员用户

## 语法
<a name="r_ALTER_SYSTEM-synopsis"></a>

```
ALTER SYSTEM SET system-level-configuration = {true| t | on | false | f | off}
```

## 参数
<a name="r_ALTER_SYSTEM-parameters"></a>

 *system-level-configuration*   
系统级配置。有效值：`data_catalog_auto_mount` 和 `metadata_security`。

\$1true\$1 t \$1 on \$1 false \$1 f \$1 off\$1   
用于激活或停用系统级配置的值。`true`、`t` 或 `on` 表示要激活配置。`false`、`f` 或 `off` 表示要停用配置。

## 使用说明
<a name="r_ALTER_SYSTEM-usage-notes"></a>

对于预置集群，对 `data_catalog_auto_mount` 的更改将在集群下次重新引导时生效。有关更多信息，请参阅《Amazon Redshift 管理指南》**中的[重新引导集群](https://docs.aws.amazon.com/redshift/latest/mgmt/managing-clusters-console.html#reboot-cluster)。

对于无服务器工作组，对 `data_catalog_auto_mount` 的更改不会立即生效。

## 示例
<a name="r_ALTER_SYSTEM-examples"></a>

以下示例开启了自动挂载 AWS Glue Data Catalog 的功能。

```
ALTER SYSTEM SET data_catalog_auto_mount = true;
```

以下示例开启了元数据安全性。

```
ALTER SYSTEM SET metadata_security = true;
```

### 设置默认身份命名空间
<a name="r_ALTER_SYSTEM-identity"></a>

此示例特定于使用身份提供者。您可以将 Redshift 与 IAM Identity Center 和身份提供者集成，来集中管理 Redshift 和其它 AWS 服务的身份。

以下示例显示了如何为系统设置默认身份命名空间。这样做后，将可以更轻松地运行 GRANT 和 CREATE 语句，因为您不必包括此命名空间来作为每个身份的前缀。

```
ALTER SYSTEM SET default_identity_namespace = 'MYCO';
```

运行命令后，您可以运行如下语句：

```
GRANT SELECT ON TABLE mytable TO alice;

GRANT UPDATE ON TABLE mytable TO salesrole;
               
CREATE USER bob password 'md50c983d1a624280812631c5389e60d48c';
```

设置默认身份命名空间的效果是，每个身份都不需要将其作为前缀。在本例中，`alice` 替换为 `MYCO:alice`。如果包含任何身份，就会发生这种情况。有关将身份提供者与 Redshift 结合使用的更多信息，请参阅[将 Redshift 与 IAM Identity Center 连接，为用户提供单点登录体验](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-idp-connect.html)。

有关与 IAM Identity Center 的 Redshift 配置相关的设置的更多信息，请参阅 [SET](r_SET.md) 和 [ALTER IDENTITY PROVIDER](r_ALTER_IDENTITY_PROVIDER.md)。

# ALTER TABLE
<a name="r_ALTER_TABLE"></a>

此命令更改 Amazon Redshift 表或 Amazon Redshift Spectrum 外部表的定义。此命令更新 [CREATE TABLE](r_CREATE_TABLE_NEW.md) 或 [CREATE EXTERNAL TABLE](r_CREATE_EXTERNAL_TABLE.md) 设置的值和属性。您可以在视图上使用 ALTER TABLE 来实现行级别安全性（RLS）。

您不能在以下事务块内的外部表上运行 ALTER TABLE (BEGIN ... END)。有关事务的更多信息，请参阅 [Amazon Redshift 中的隔离级别](c_serial_isolation.md)。

除非文档中明确规定可以在表更改时查询表或执行其他操作，否则 ALTER TABLE 会锁定表的读写操作，直到包含 ALTER TABLE 操作的事务完成。

## 所需的权限
<a name="r_ALTER_TABLE-privileges"></a>

修改表的用户需要适当的权限才能成功执行命令。根据具体的 ALTER TABLE 命令，需要以下权限之一。
+ Superuser
+ 具有 ALTER TABLE 权限的用户
+ 对模式拥有 USAGE 权限的表拥有者

## 语法
<a name="r_ALTER_TABLE-synopsis"></a>

```
ALTER TABLE table_name
{
ADD table_constraint
| DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ]
| OWNER TO new_owner
| RENAME TO new_name
| RENAME COLUMN column_name TO new_name
| ALTER COLUMN column_name TYPE updated_varchar_data_type_size
| ALTER COLUMN column_name ENCODE new_encode_type
| ALTER COLUMN column_name ENCODE encode_type,
| ALTER COLUMN column_name ENCODE encode_type, .....;
| ALTER DISTKEY column_name
| ALTER DISTSTYLE ALL
| ALTER DISTSTYLE EVEN
| ALTER DISTSTYLE KEY DISTKEY column_name
| ALTER DISTSTYLE AUTO
| ALTER [COMPOUND] SORTKEY ( column_name [,...] )
| ALTER SORTKEY AUTO
| ALTER SORTKEY NONE
| ALTER ENCODE AUTO
| ADD [ COLUMN ] column_name column_type
  [ DEFAULT default_expr ]
  [ ENCODE encoding ]
  [ NOT NULL | NULL ]
  [ COLLATE { CASE_SENSITIVE | CS | CASE_INSENSITIVE | CI } ] |
| DROP [ COLUMN ] column_name [ RESTRICT | CASCADE ] 
| ROW LEVEL SECURITY { ON | OFF } [ CONJUNCTION TYPE { AND | OR } ] [ FOR DATASHARES ]
| MASKING { ON | OFF } FOR DATASHARES }

where table_constraint is:

[ CONSTRAINT constraint_name ]
{ UNIQUE ( column_name [, ... ] )
| PRIMARY KEY ( column_name [, ... ] )
| FOREIGN KEY (column_name [, ... ] )
   REFERENCES  reftable [ ( refcolumn ) ]}

The following options apply only to external tables:

SET LOCATION { 's3://bucket/folder/' | 's3://bucket/manifest_file' }
| SET FILE FORMAT format |
| SET TABLE PROPERTIES ('property_name'='property_value')
| PARTITION ( partition_column=partition_value [, ...] )
  SET LOCATION { 's3://bucket/folder' |'s3://bucket/manifest_file' }
| ADD [IF NOT EXISTS]
    PARTITION ( partition_column=partition_value [, ...] ) LOCATION { 's3://bucket/folder' |'s3://bucket/manifest_file' }
    [, ... ]
| DROP PARTITION ( partition_column=partition_value [, ...] )
```

要减少运行 ALTER TABLE 命令的时间，可以结合使用 ALTER TABLE 命令的一些子句。

Amazon Redshift 支持以下 ALTER TABLE 子句组合：

```
ALTER TABLE tablename ALTER SORTKEY (column_list), ALTER DISTKEY column_Id;
ALTER TABLE tablename ALTER DISTKEY column_Id, ALTER SORTKEY (column_list);
ALTER TABLE tablename ALTER SORTKEY (column_list), ALTER DISTSTYLE ALL;
ALTER TABLE tablename ALTER DISTSTYLE ALL, ALTER SORTKEY (column_list);
```

## 参数
<a name="r_ALTER_TABLE-parameters"></a>

 *table\$1name*   
要修改的表的名称。只指定表的名称，或者通过格式 *schema\$1name.table\$1name* 使用特定 schema。外部表必须通过一个外部 schema 名称进行限定。如果您使用 ALTER TABLE 语句重命名视图或更改其拥有者，您还可以指定视图名称。表名称的最大长度为 127 个字节；更长的名称将被截断为 127 个字节。您可以使用 UTF-8 多字节字符，每个字符最多为四个字节。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。

ADD *table\$1constraint*   
用于将指定约束添加到表的子句。有关有效 *table\$1constraint* 值的描述，请参阅 [CREATE TABLE](r_CREATE_TABLE_NEW.md)。  
您不能将主键约束添加到可为空的列。如果列最初是使用 NOT NULL 约束创建的，您可以添加主键约束。

DROP CONSTRAINT *constraint\$1name*   
用于从表中删除指定约束的子句。要删除约束，请指定约束名称而不是约束类型。要查看表约束名称，请运行以下查询。  

```
select constraint_name, constraint_type
from information_schema.table_constraints;
```

RESTRICT   
用于仅删除指定约束的子句。RESTRICT 是 DROP CONSTRAINT 的一个选项。RESTRICT 不能与 CASCADE 一起使用。

CASCADE   
用于删除指定约束和依赖于该约束的任何内容的子句。CASCADE 是 DROP CONSTRAINT 的选项。CASCADE 不能与 RESTRICT 一起使用。

OWNER TO *new\$1owner*   
用于将表（或视图）的所有者更改为 *new\$1owner* 值的子句。

RENAME TO *new\$1name*   
用于将表（或视图）重命名为 *new\$1name* 中指定的值的子句。表名称的最大长度为 127 个字节；更长的名称将被截断为 127 个字节。  
您不能将永久表重命名为以“\$1”开头的表。名称以“\$1”开头的表是临时表。  
您无法重命名外部表。

ALTER COLUMN *column\$1name* TYPE *updated\$1varchar\$1data\$1type\$1size*   
这是一个更改定义为 VARCHAR 数据类型的列大小的子句。此子句仅支持修改 VARCHAR 数据类型的大小。请考虑以下限制：  
+ 您无法修改具有 BYTEDICT、RUNLENGTH、TEXT255 或 TEXT32K 压缩编码的列。
+ 您无法将大小减少到小于现有数据的最大大小。
+ 您无法更改具有默认值的列。
+ 您无法更改具有 UNIQUE、PRIMARY KEY 或 FOREIGN KEY 的列。
+ 您不能更改以下事务块中的列：(BEGIN ... END)。有关事务的更多信息，请参阅 [Amazon Redshift 中的隔离级别](c_serial_isolation.md)。

ALTER COLUMN *column\$1name* ENCODE *new\$1encode\$1type*   
更改列的压缩编码的子句。如果为列指定压缩编码，则表不再设置为 ENCODE AUTO。有关压缩编码的信息，请参阅[列压缩，减小存储数据的大小](t_Compressing_data_on_disk.md)。  
在更改列的压缩编码时，表仍可供查询。  
请考虑以下限制：  
+ 您不能将列更改为与当前为该列定义的相同的编码。
+ 不能使用交错排序键更改表中列的编码。

ALTER COLUMN *column\$1name* ENCODE *encode\$1type*, ALTER COLUMN *column\$1name* ENCODE *encode\$1type*, .....;  
更改单个命令中多个列的压缩编码的子句。有关压缩编码的信息，请参阅[列压缩，减小存储数据的大小](t_Compressing_data_on_disk.md)。  
在更改列的压缩编码时，表仍可供查询。  
 请考虑以下限制：  
+ 您不能在单个命令中多次将列更改为相同或不同的编码类型。
+ 您不能将列更改为与当前为该列定义的相同的编码。
+ 不能使用交错排序键更改表中列的编码。

ALTER DISTSTYLE ALL  
用于将表的现有分配样式更改为 `ALL` 的子句。请考虑以下事项：  
+ ALTER DISTSTYLE、ALTER SORTKEY 和 VACUUM 不能同时对同一个表运行。
  + 如果 VACUUM 当前正在运行，则运行 ALTER DISTSTYLE ALL 将返回错误。
  + 如果 ALTER DISTSTYLE ALL 正在运行，则不在表上启动后台 vacuum。
+ 对于具有交错排序键和临时表的表，不支持 ALTER DISTSTYLE ALL 命令。
+ 如果分配方式以前被定义为 AUTO，则表不再是自动表优化的候选项。
有关 DISTSTYLE ALL 的更多信息，请参阅 [CREATE TABLE](r_CREATE_TABLE_NEW.md)。

ALTER DISTSTYLE EVEN  
用于将表的现有分配样式更改为 `EVEN` 的子句。请考虑以下事项：  
+ ALTER DISTSYTLE、ALTER SORTKEY 和 VACUUM 不能同时对同一个表运行。
  + 如果 VACUUM 当前正在运行，则运行 ALTER DISTSTYLE EVEN 将返回错误。
  + 如果 ALTER DISTSTYLE EVEN 正在运行，则不在表上启动后台 Vacuum。
+ 对于具有交错排序键和临时表的表，不支持 ALTER DISTSTYLE EVEN 命令。
+ 如果分配方式以前被定义为 AUTO，则表不再是自动表优化的候选项。
有关 DISTSTYLE EVEN 的更多信息，请参阅 [CREATE TABLE](r_CREATE_TABLE_NEW.md)。

ALTER DISTKEY *column\$1name* 或 ALTER DISTSTYLE KEY DISTKEY *column\$1name*  
一个子句，可更改用作表的分配键的列。请考虑以下事项：  
+ 不能在同一个表上并发运行 VACUUM 和 ALTER DISTKEY。
  + 如果 VACUUM 已经运行，则 ALTER DISTKEY 返回错误。
  + 如果 ALTER DISTKEY 正在运行，则不在表上启动后台 Vacuum。
  + 如果 ALTER DISTKEY 正在运行，则前台 vacuum 会返回错误。
+ 您一次只能在一个表上运行一个 ALTER DISTKEY 命令。
+ 具有交错排序键的表不支持 ALTER DISTKEY 命令。
+ 如果分配方式以前被定义为 AUTO，则表不再是自动表优化的候选项。
指定 DISTSTYLE KEY 时，按 DISTKEY 列中的值分配数据。有关 DISTSTYLE 的更多信息，请参阅 [CREATE TABLE](r_CREATE_TABLE_NEW.md)。

ALTER DISTSTYLE AUTO  
用于将表的现有分配方式更改为 AUTO 的子句。  
将分配方式更改为 AUTO 时，表的分配模式设置为以下内容：  
+ 带有 DISTSTYLE ALL 的小型表被转换为 AUTO(ALL)。
+ 带有 DISTSTYLE EVEN 的小型表被转换为 AUTO(ALL)。
+ 带有 DISTSTYLE KEY 的小型表被转换为 AUTO(ALL)。
+ 带有 DISTSTYLE ALL 的大型表被转换为 AUTO(EVEN)。
+ 带有 DISTSTYLE EVEN 的大型表被转换为 AUTO(EVEN)。
+ 带有 DISTSTYLE KEY 的大型表被转换为 AUTO(KEY)，且 DISTKEY 被保留。在这种情况下，Amazon Redshift 不对表进行任何更改。
如果 Amazon Redshift 确定新的分配方式或密钥将提高查询的性能，那么 Amazon Redshift 将来可能会更改您的表格的分配方式或键。例如，Amazon Redshift 可能会将 DISTSTYLE 为 AUTO(KEY) 的表转换为 AUTO(EVEN)，反之亦然。有关分发密钥被更改时行为的更多信息（包括数据重新分发和锁定），请参阅 [Amazon Redshift Advisor 建议](https://docs.aws.amazon.com/redshift/latest/dg/advisor-recommendations.html#alter-diststyle-distkey-recommendation)。  
有关 DISTSTYLE AUTO 的更多信息，请参阅[CREATE TABLE](r_CREATE_TABLE_NEW.md)。  
要查看表的分配方式，请查询 SVV\$1TABLE\$1INFO 系统目录视图。有关更多信息，请参阅 [SVV\$1TABLE\$1INFO](r_SVV_TABLE_INFO.md)。要查看 Amazon Redshift Advisor 对表的建议，请查询 SVV\$1ALTER\$1TABLE\$1RECOMMENDATIONS 系统目录视图。有关更多信息，请参阅 [SVV\$1ALTER\$1TABLE\$1RECOMMENDATIONS](r_SVV_ALTER_TABLE_RECOMMENDATIONS.md)。要查看 Amazon Redshift 所采取的操作，请查询 SVL\$1AUTO\$1WORKER\$1ACTION 系统目录视图。有关更多信息，请参阅 [SVL\$1AUTO\$1WORKER\$1ACTION](r_SVL_AUTO_WORKER_ACTION.md)。

ALTER [COMPOUND] SORTKEY ( *column\$1name* [,...] )  
一个旨在更改或添加用于表的排序键的子句。临时表不支持 ALTER SORTKEY。  
当您更改排序键时，新排序键或原始排序键中列的压缩编码可能会更改。如果没有为表显式定义编码，则 Amazon Redshift 按如下方式自动分配压缩编码：  
+ 为定义为排序键的列分配 RAW 压缩。
+ 为定义为 BOOLEAN、REAL 或 DOUBLE PRECISION 数据类型的列分配 RAW 压缩。
+ 定义为 SMALLINT、INTEGER、BIGINT、DECIMAL、DATE、TIME、TIMETZT、IMESTAMP 或 TIMESTAMPTZ 的列分配了 AZ64 压缩。
+ 定义为 CHAR 或 VARCHAR 的列分配了 LZO 压缩。
请考虑以下事项：  
+ 最多可以为每个表的排序键定义 400 列。
+ 您可以将交错排序键更改为复合排序键或没有排序键。但是，您不能将复合排序键更改为交错排序键。
+ 如果排序键以前被定义为 AUTO，则表不再是自动表优化的候选项。
+ Amazon Redshift 建议对定义为排序键的列使用 RAW 编码（不压缩）。当您更改列以将其选择为排序键时，列的压缩将更改为 RAW 压缩（无压缩）。这将增加表所需的存储空间。表大小的增加程度取决于特定的表定义和表格内容。有关压缩的更多信息，请参阅[压缩编码](c_Compression_encodings.md) 
将数据加载到表中时，将按照排序键的顺序加载数据。更改排序键时，Amazon Redshift 对数据重新排序。有关 SORTKEY 的更多信息，请参阅 [CREATE TABLE](r_CREATE_TABLE_NEW.md)。

ALTER SORTKEY AUTO  
一个可更改目标表的排序键或将其添加到 AUTO 的子句。临时表不支持 ALTER SORTKEY AUTO。  
当您将排序键更改为 AUTO 时，Amazon Redshift 会保留表的现有排序键。  
如果 Amazon Redshift 确定新的排序键将提高查询的性能，那么 Amazon Redshift 将来可能会更改您的表的排序键。  
有关 SORTKEY AUTO 的更多信息，请参阅[CREATE TABLE](r_CREATE_TABLE_NEW.md)。  
要查看表的排序键，请查询 SVV\$1TABLE\$1INFO 系统目录视图。有关更多信息，请参阅 [SVV\$1TABLE\$1INFO](r_SVV_TABLE_INFO.md)。要查看 Amazon Redshift Advisor 对表的建议，请查询 SVV\$1ALTER\$1TABLE\$1RECOMMENDATIONS 系统目录视图。有关更多信息，请参阅 [SVV\$1ALTER\$1TABLE\$1RECOMMENDATIONS](r_SVV_ALTER_TABLE_RECOMMENDATIONS.md)。要查看 Amazon Redshift 所采取的操作，请查询 SVL\$1AUTO\$1WORKER\$1ACTION 系统目录视图。有关更多信息，请参阅 [SVL\$1AUTO\$1WORKER\$1ACTION](r_SVL_AUTO_WORKER_ACTION.md)。

ALTER SORTKEY NONE  
删除目标表的排序键的子句。  
如果排序键以前被定义为 AUTO，则表不再是自动表优化的候选项。

ALTER ENCODE AUTO  
将目标表列的编码类型更改为 AUTO 的子句。当您将编码更改为 AUTO 时，Amazon Redshift 会保留表中列的现有编码类型。然后，如果 Amazon Redshift 确定新的编码类型可以提高查询性能，则 Amazon Redshift 可以更改表列的编码类型。  
如果您更改一个或多个列以指定编码，Amazon Redshift 将不再自动调整表中所有列的编码。这些列保留当前的编码设置。  
以下操作不会影响表的 ENCODE AUTO 设置：  
+ 重命名表。
+ 更改表的 DISTSTYLE 或 SORTKEY 设置。
+ 使用 ENCODE 设置添加或删除列。
+ 使用 COPY 命令的 COMPUPDATE 选项。有关更多信息，请参阅 [数据加载操作](copy-parameters-data-load.md)。
要查看表的编码，请查询 SVV\$1TABLE\$1INFO 系统目录视图。有关更多信息，请参阅 [SVV\$1TABLE\$1INFO](r_SVV_TABLE_INFO.md)。

RENAME COLUMN *column\$1name* TO *new\$1name*   
用于将列重命名为 *new\$1name* 中指定的值的子句。列名称的最大长度为 127 个字节；更长的名称将被截断为 127 个字节。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。

ADD [ COLUMN ] *column\$1name*   
用于将具有指定名称的列添加到表的子句。您在每个 ALTER TABLE 语句中只能修改一列。  
您无法添加用作表的分配键 (DISTKEY) 或排序键 (SORTKEY) 的列。  
 您不能使用 ALTER TABLE ADD COLUMN 命令修改以下表和列属性：  
+ UNIQUE
+ PRIMARY KEY
+ REFERENCES（外键）
+ IDENTITY 或 GENERATED BY DEFAULT AS IDENTITY
列名称的最大长度为 127 个字节；更长的名称将被截断为 127 个字节。可在单个表中定义的列的最大数目为 1,600。  
在将列添加到外部表时，会应用以下限制：  
+ 您无法向列约束为 DEFAULT、ENCODE、NOT NULL 或 NULL 的外部表中添加列。
+ 您无法向使用 AVRO 文件格式定义的外部表中添加列。
+ 如果启用 pseudocolumns，则可在单个表中定义的最大列数为 1,598。如果未启用 pseudocolumns，则可在单个表中定义的最大列数为 1600。
有关更多信息，请参阅 [CREATE EXTERNAL TABLE](r_CREATE_EXTERNAL_TABLE.md)。

 *column\$1type*   
要添加的列的数据类型。对于 CHAR 和 VARCHAR 列，您可以使用 MAX 关键字而不是声明最大长度。MAX 将最大长度设置为 4096 字节（对于 CHAR）或 65535 字节（对于 VARCHAR）。GEOMETRY 对象的最大大小为 1048447 字节。  
有关 Amazon Redshift 支持的数据类型的信息，请参阅[数据类型](c_Supported_data_types.md)。

DEFAULT *default\$1expr*   <a name="alter-table-default"></a>
用于为列分配默认数据值的子句。*default\$1expr* 的数据类型必须匹配列的数据类型。DEFAULT 值必须是无变量的表达式。不允许子查询、对当前表中其他列的交叉引用和用户定义的函数。  
*default\$1expr* 在未为列指定值的任何 INSERT 操作中使用。如果未指定默认值，则列的默认值为 null。  
如果 COPY 操作在具有 DEFAULT 值和 NOT NULL 约束的列上遇到空字段，则 COPY 命令将插入 *default\$1expr* 值。  
外部表不支持 DEFAULT。

ENCODE *encoding*   
列的压缩编码。预设情况下，如果您没有为表中的任何列指定压缩编码，或者您为表指定了 ENCODE AUTO 选项，Amazon Redshift 会自动管理表中所有列的压缩编码。  
如果您为表中的任何列指定压缩编码，或者您没有为表指定 ENCODE AUTO 选项，Amazon Redshift 会自动将压缩编码分配给您未指定压缩编码的列，如下所示：  
+ 默认情况下，会为临时表中的所有列分配 RAW 压缩。
+ 为定义为排序键的列分配 RAW 压缩。
+ 定义为 BOOLEAN、REAL、DOUBLE PRECISION、GEOMETRY 或 GEOGRAPHY 数据类型的列分配了 RAW 压缩。
+ 定义为 SMALLINT、INTEGER、BIGINT、DECIMAL、DATE、TIME、TIMETZ、TIMESTAMP 或 TIMESTAMPTZ 的列分配了 AZ64 压缩。
+ 定义为 CHAR、VARCHAR 或 VARBYTE 的列分配了 LZO 压缩。
如果您不希望压缩某个列，请显式指定 RAW 编码。
支持以下[compression encodings](c_Compression_encodings.md#compression-encoding-list)：  
+ AZ64
+ BYTEDICT
+ DELTA
+ DELTA32K
+ LZO
+ MOSTLY8
+ MOSTLY16
+ MOSTLY32
+ RAW（无压缩）
+ RUNLENGTH
+ TEXT255
+ TEXT32K
+ ZSTD
外部表不支持 ENCODE。

NOT NULL \$1 NULL   
NOT NULL 指定列中不允许包含 null 值。NULL（默认值）指定列接受 null 值。  
外部表不支持 NOT NULL 和 NULL。

COLLATE \$1 CASE\$1SENSITIVE \$1 CS \$1 CASE\$1INSENSITIVE \$1 CI \$1  
指定列中的字符串搜索或比较是区分大小写还是不区分大小写的子句。默认值与数据库的当前区分大小写的配置相同。  
要查找数据库排序规则信息，请使用以下命令：  

```
SELECT db_collation();
                     
db_collation
----------------
 case_sensitive
(1 row)
```
CASE\$1SENSITIVE 和 CS 可以互换，生成的结果相同。同样，CASE\$1INSENSITIVE 和 CI 可以互换，生成的结果相同。

DROP [ COLUMN ] *column\$1name*   
要从表中删除的列的名称。  
您无法删除表中的最后一列。表必须有至少一列。  
您无法删除用作表的分配键 (DISTKEY) 或排序键 (SORTKEY) 的列。如果列具有任何从属对象，例如视图、主键、外键或 UNIQUE 限制，则 DROP COLUMN 的默认行为是 RESTRICT。  
对外部表中的列执行 DROP 时，会应用以下限制：  
+ 如果列用作分区，则您无法哦那个外部表中删除列。
+ 您无法从使用 AVRO 文件格式定义的外部表中删除列。
+ 对于外部表，将会忽略 RESTRICT 和 CASCADE。
+ 除非删除或分离策略，否则您无法删除策略定义中引用的策略表中的列。在指定 CASCADE 选项时，这也将适用。您可以删除策略表中的其他列。
有关更多信息，请参阅 [CREATE EXTERNAL TABLE](r_CREATE_EXTERNAL_TABLE.md)。

RESTRICT   
在下面这些情况下，与 DROP COLUMN 一起使用时，RESTRICT 表示不删除要删除的列：  
+ 定义的视图引用了要删除的列
+ 外键引用了该列
+ 该列参与了多部分键
RESTRICT 不能与 CASCADE 一起使用。  
对于外部表，将会忽略 RESTRICT 和 CASCADE。

CASCADE   
在与 DROP COLUMN 配合使用时，删除指定的列以及依赖该列的任何内容。CASCADE 不能与 RESTRICT 一起使用。  
对于外部表，将会忽略 RESTRICT 和 CASCADE。

以下选项仅适用于外部表。

SET LOCATION \$1 's3://*bucket/folder*/' \$1 's3://*bucket/manifest\$1file*' \$1  
包含数据文件的 Amazon S3 文件夹的路径或包含 Amazon S3 对象路径列表的清单文件。桶必须与 Amazon Redshift 集群位于同一 AWS 区域。有关受支持的 AWS 区域的列表，请参阅[Amazon Redshift Spectrum 限制](c-spectrum-considerations.md)。有关使用清单文件的更多信息，请参阅 CREATE EXTERNAL TABLE [参数](r_CREATE_EXTERNAL_TABLE.md#r_CREATE_EXTERNAL_TABLE-parameters) 参考中的 LOCATION。

SET FILE FORMAT *format*  
外部数据文件的文件格式。  
有效格式如下所示：  
+ AVRO 
+ PARQUET
+ RCFILE
+ SEQUENCEFILE
+ TEXTFILE 

SET TABLE PROPERTIES ( '*property\$1name*'='*property\$1value*')   
一个子句，用于设置外部表的表属性的表定义。  
表属性区分大小写。  
'numRows'='*row\$1count*'  
用于为表定义设置 numRows 值的属性。若要显式更新外部表的统计数据，请设置 numRows 属性来指示表的大小。Amazon Redshift 不分析外部表来生成表统计数据，查询优化程序会使用这些统计数据来生成查询计划。如果没有为外部表设置表统计数据，则 Amazon Redshift 会生成查询执行计划。此计划是基于“外部表较大，本地表较小”的假设生成的。  
'skip.header.line.count'='*line\$1count*'  
用于设置在每个源文件开头要跳过的行数的属性。

PARTITION ( *partition\$1column*=*partition\$1value* [, ...] SET LOCATION \$1 's3://*bucket*/*folder*' \$1 's3://*bucket*/*manifest\$1file*' \$1  
用于为一个或多个分区列设置新位置的子句。

ADD [ IF NOT EXISTS ] PARTITION ( *partition\$1column*=*partition\$1value* [, ...] ) LOCATION \$1 's3://*bucket*/*folder*' \$1 's3://*bucket*/*manifest\$1file*' \$1 [, ... ]  
用于添加一个或多个分区的子句。您可以使用单个 ALTER TABLE … ADD 语句指定多个 PARTITION 子句。  
如果使用 AWS Glue 目录，则可以使用单个 ALTER TABLE 语句最多添加 100 个分区。
IF NOT EXISTS 子句指示，如果指定的分区已存在，命令应不进行任何更改。它还指示该命令应返回分区存在的消息，而不是以错误终止。此子句在编写脚本时很有用，可使脚本在 ALTER TABLE 尝试添加已存在的分区时不会失败。

DROP PARTITION (*partition\$1column*=*partition\$1value* [, ...] )   
用于删除指定分区的子句。删除分区只会更改外部表元数据。Amazon S3 上的数据不受影响。

ROW LEVEL SECURITY \$1 ON \$1 OFF \$1 [ CONJUNCTION TYPE \$1 AND \$1 OR \$1 ] [ FOR DATASHARES ]  
一个对关系开启或关闭行级安全性的子句。  
在为关系开启行级安全性后，您只能读取行级安全策略允许您访问的行。如果没有策略向您授予对关系的访问权限，您将看不到关系中的任何行。只有超级用户和拥有 `sys:secadmin` 角色的用户或角色才能设置 ROW LEVEL SECURITY 子句。有关更多信息，请参阅 [行级别安全性](t_rls.md)。连接的数据库或具有 Amazon Redshift 联合身份验证权限的数据库支持此语句。具有 Amazon Redshift 联合身份验证权限的数据库不支持 FOR DATASHARES 子句。  
+ [ CONJUNCTION TYPE \$1 AND \$1 OR \$1 ] 

  一个允许您为关系选择行级安全策略的联接类型的子句。将多个行级安全策略附加到关系时，可以将这些策略与 AND 或 OR 子句合并。默认情况下，Amazon Redshift 将 RLS 策略与 AND 子句合并。具有 `sys:secadmin` 角色的超级用户、用户或角色可以使用此子句为关系定义行级安全策略的联接类型。有关更多信息，请参阅 [为每个用户组合多个策略](t_rls_combine_policies.md)。
+ FOR DATASHARES

  一个子句，用于确定是否可以通过数据共享访问受 RLS 保护的关系。默认情况下，无法通过数据共享访问受 RLS 保护的关系。使用此子句运行的 ALTER TABLE ROW LEVEL SECURITY 命令只会影响关系的数据共享可访问性属性。ROW LEVEL SECURITY 属性未更改。

   如果您允许通过数据共享访问受 RLS 保护的关系，则该关系在使用者端数据共享数据库中没有行级安全性。该关系在生产者端保留其 RLS 属性。

MASKING \$1 ON \$1 OFF \$1 FOR DATASHARES  
一个子句，用于确定是否可以通过数据共享访问受 DDM 保护的关系。默认情况下，无法通过数据共享访问受 DDM 保护的关系。如果您使受 DDM 保护的关系可通过数据共享进行访问，则该关系在使用者端数据共享数据库中不会具有掩蔽保护。该关系在生产者端保留其掩蔽属性。只有超级用户和拥有 `sys:secadmin` 角色的用户或角色才能设置 MASKING FOR DATASHARES 子句。有关更多信息，请参阅 [动态数据掩蔽](t_ddm.md)。

## 示例
<a name="r_ALTER_TABLE-examples"></a>

有关说明 ALTER TABLE 命令用法的示例，请参阅以下内容。
+ [ALTER TABLE 示例](r_ALTER_TABLE_examples_basic.md)
+ [ALTER EXTERNAL TABLE 示例](r_ALTER_TABLE_external-table.md)
+ [ALTER TABLE ADD 和 DROP COLUMN 示例](r_ALTER_TABLE_COL_ex-add-drop.md)

# ALTER TABLE 示例
<a name="r_ALTER_TABLE_examples_basic"></a>

以下示例演示了 ALTER TABLE 命令的基本用法。

## 重命名表或视图
<a name="r_ALTER_TABLE_examples_basic-rename-a-table"></a>

以下命令将 USERS 表重命名为 USERS\$1BKUP：

```
alter table users
rename to users_bkup;
```

 您还可以使用此类型的命令来重命名视图。

## 更改表或视图的所有者
<a name="r_ALTER_TABLE_examples_basic-change-the-owner-of-a-table-or-view"></a>

以下命令将 VENUE 表所有者更改为用户 DWUSER：

```
alter table venue
owner to dwuser;
```

以下命令创建一个视图，然后更改其所有者：

```
create view vdate as select * from date;
alter table vdate owner to vuser;
```

## 重命名列
<a name="r_ALTER_TABLE_examples_basic-rename-a-column"></a>

以下命令将 VENUE 表中的 VENUESEATS 列重命名为 VENUESIZE：

```
alter table venue
rename column venueseats to venuesize;
```

## 删除表约束
<a name="r_ALTER_TABLE_examples_drop-constraint"></a>

要删除表约束（例如主键、外键或唯一约束），请先查找约束的内部名称。然后在 ALTER TABLE 命令中指定约束名称。以下示例查找 CATEGORY 表的约束，然后删除名为 `category_pkey` 的主键。

```
select constraint_name, constraint_type
from information_schema.table_constraints
where constraint_schema ='public'
and table_name = 'category';

constraint_name | constraint_type
----------------+----------------
category_pkey   | PRIMARY KEY

alter table category
drop constraint category_pkey;
```

## 更改 VARCHAR 列
<a name="r_ALTER_TABLE_examples_alter-column"></a>

为了节省存储空间，您最初可以使用 VARCHAR 列定义一个表，这些列具有满足当前数据要求所需的最小大小。以后，要容纳更长的字符串，您可以更改表以增加列大小。

以下示例将 EVENTNAME 列大小增加到 VARCHAR(300)。

```
alter table event alter column eventname type varchar(300);
```

## 更改 VARBYTE 列
<a name="r_ALTER_TABLE_examples_alter-varbyte-column"></a>

为了节省存储空间，您最初可以使用 VARBYTE 列定义一个表，这些列具有满足当前数据要求所需的最小大小。以后，要容纳更长的字符串，您可以更改表以增加列大小。

以下示例将 EVENTNAME 列大小增加到 VARBYTE(300)。

```
alter table event alter column eventname type varbyte(300);
```

## 更改列的压缩编码
<a name="r_ALTER_TABLE_examples_alter-column-encoding"></a>

您可以更改列的压缩编码。您可以在下面找到一组演示此方法的示例。这些示例的表定义如下。

```
create table t1(c0 int encode lzo, c1 bigint encode zstd, c2 varchar(16) encode lzo, c3 varchar(32) encode zstd);
```

以下语句将列 c0 的压缩编码从 LZO 编码更改为 AZ64 编码。

```
alter table t1 alter column c0 encode az64;
```

以下语句将列 c1 的压缩编码从 Zstandard 编码更改为 AZ64 编码。

```
alter table t1 alter column c1 encode az64;
```

以下语句将列 c2 的压缩编码从 LZO 编码更改为 Byte-dictionary 编码。

```
alter table t1 alter column c2 encode bytedict;
```

以下语句将列 c3 的压缩编码从 Zstandard 编码更改为 Runlength 编码。

```
alter table t1 alter column c3 encode runlength;
```

## 修改 DISTSTYLE KEY DISTKEY 列
<a name="r_ALTER_TABLE_examples_alter-distkey"></a>

以下示例显示如何更改表的 DISTSTYLE 和 DISTKEY。

使用 EVEN 分配样式创建表 SVV\$1TABLE\$1INFO 视图显示 DISTSTYLE 为 EVEN。

```
create table inventory(
  inv_date_sk int4 not null ,
  inv_item_sk int4 not null ,
  inv_warehouse_sk int4 not null ,
  inv_quantity_on_hand int4
) diststyle even;

Insert into inventory values(1,1,1,1);

select "table", "diststyle" from svv_table_info;

   table   |   diststyle
-----------+----------------
 inventory |     EVEN
```

将表 DISTKEY 更改为 `inv_warehouse_sk`。SVV\$1TABLE\$1INFO 视图将 `inv_warehouse_sk` 列显示为结果分配密钥。

```
alter table inventory alter diststyle key distkey inv_warehouse_sk;

select "table", "diststyle" from svv_table_info;

   table   |       diststyle
-----------+-----------------------
 inventory | KEY(inv_warehouse_sk)
```

将表 DISTKEY 更改为 `inv_item_sk`。SVV\$1TABLE\$1INFO 视图将 `inv_item_sk` 列显示为结果分配密钥。

```
alter table inventory alter distkey inv_item_sk;

select "table", "diststyle" from svv_table_info;

   table   |       diststyle
-----------+-----------------------
 inventory | KEY(inv_item_sk)
```

## 将表更改为 DISTSTYLE ALL
<a name="r_ALTER_TABLE_examples_alter-diststyle-all"></a>

以下示例演示如何将表更改为 DISTSTYLE ALL。

使用 EVEN 分配样式创建表 SVV\$1TABLE\$1INFO 视图显示 DISTSTYLE 为 EVEN。

```
create table inventory(
  inv_date_sk int4 not null ,
  inv_item_sk int4 not null ,
  inv_warehouse_sk int4 not null ,
  inv_quantity_on_hand int4
) diststyle even;

Insert into inventory values(1,1,1,1);

select "table", "diststyle" from svv_table_info;

   table   |   diststyle
-----------+----------------
 inventory |     EVEN
```

将表 DISTSTYLE 更改为 ALL。SVV\$1TABLE\$1INFO 视图显示已更改的 DISTSYTLE。

```
alter table inventory alter diststyle all;

select "table", "diststyle" from svv_table_info;

   table   |   diststyle
-----------+----------------
 inventory |     ALL
```

## 更改表 SORTKEY
<a name="r_ALTER_TABLE_examples_alter-sortkey"></a>

您可以将表更改为具有复合排序键或没有排序键。

在以下表定义中，表 `t1` 是使用交错排序键定义的。

```
create table t1 (c0 int, c1 int) interleaved sortkey(c0, c1);
```

以下命令将表从交错排序键更改为复合排序键。

```
alter table t1 alter sortkey(c0, c1);
```

以下命令对表进行了修改，删除了交错排序键。

```
alter table t1 alter sortkey none;
```

在以下表定义中，表 `t1` 将列 `c0` 定义为排序键。

```
create table t1 (c0 int, c1 int) sortkey(c0);
```

以下命令将表 `t1` 更改为复合排序键。

```
alter table t1 alter sortkey(c0, c1);
```

## 将表更改为 ENCODE AUTO
<a name="r_ALTER_TABLE_examples_alter-encode-auto"></a>

以下示例说明如何将表更改为 ENCODE AUTO。

此示例的表定义如下。列 `c0` 使用编码类型 AZ64 进行定义，列 `c1` 使用编码类型 LZO 定义。

```
create table t1(c0 int encode AZ64, c1 varchar encode LZO);
```

对于此表，以下语句将编码更改为 AUTO。

```
alter table t1 alter encode auto;
```

以下示例说明如何将表更改为删除 ENCODE AUTO 设置。

此示例的表定义如下。表列没有定义编码。在这种情况下，编码默认为 ENCODE AUTO。

```
create table t2(c0 int, c1 varchar);
```

对于此表，以下语句将 c0 列的编码更改为 LZO。表编码不再设置为 ENCODE AUTO。

```
alter table t2 alter column c0 encode lzo;;
```

## 修改行级别安全性控制
<a name="r_ALTER_TABLE_examples_basic-rls"></a>

以下命令将对表关闭 RLS：

```
ALTER TABLE tickit_category_redshift ROW LEVEL SECURITY OFF;
```

以下命令将对表开启 RLS：

```
ALTER TABLE tickit_category_redshift ROW LEVEL SECURITY ON;
```

以下命令将对表开启 RLS，使其可通过数据共享进行访问：

```
ALTER TABLE tickit_category_redshift ROW LEVEL SECURITY ON;
ALTER TABLE tickit_category_redshift ROW LEVEL SECURITY FOR DATASHARES OFF;
```

以下命令将对表开启 RLS，使其无法通过数据共享进行访问：

```
ALTER TABLE tickit_category_redshift ROW LEVEL SECURITY ON;
ALTER TABLE tickit_category_redshift ROW LEVEL SECURITY FOR DATASHARES ON;
```

以下命令将对表开启 RLS，并将表的 RLS 联接类型设置为 OR：

```
ALTER TABLE tickit_category_redshift ROW LEVEL SECURITY ON CONJUNCTION TYPE OR;
```

以下命令将对表开启 RLS，并将表的 RLS 联接类型设置为 AND：

```
ALTER TABLE tickit_category_redshift ROW LEVEL SECURITY ON CONJUNCTION TYPE AND;
```

# ALTER EXTERNAL TABLE 示例
<a name="r_ALTER_TABLE_external-table"></a>

以下示例使用位于美国东部（弗吉尼亚州北部）区域（`us-east-1`）AWS 区域的 Amazon S3 存储桶，以及在 [示例](r_CREATE_EXTERNAL_TABLE_examples.md) 中为 CREATE TABLE 创建的示例表。有关如何将分区与外部表一起使用的更多信息，请参阅[对 Redshift Spectrum 外部表进行分区](c-spectrum-external-tables.md#c-spectrum-external-tables-partitioning)。

以下示例将 SPECTRUM.SALES 外部表的 numRows 表属性设置为 170000 行。

```
alter table spectrum.sales
set table properties ('numRows'='170000');
```

以下示例更改 SPECTRUM.SALES 外部表的位置。

```
alter table spectrum.sales
set location 's3://redshift-downloads/tickit/spectrum/sales/';
```

以下示例将 SPECTRUM.SALES 外部表的格式更改为 Parquet。

```
alter table spectrum.sales
set file format parquet;
```

以下示例为表 SPECTRUM.SALES\$1PART 添加一个分区。

```
alter table spectrum.sales_part
add if not exists partition(saledate='2008-01-01')
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-01/';
```

以下示例为表 SPECTRUM.SALES\$1PART 添加三个分区。

```
alter table spectrum.sales_part add if not exists
partition(saledate='2008-01-01')
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-01/'
partition(saledate='2008-02-01')
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-02/'
partition(saledate='2008-03-01')
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-03/';
```

以下示例修改 SPECTRUM.SALES\$1PART 以删除包含 `saledate='2008-01-01''` 的分区。

```
alter table spectrum.sales_part
drop partition(saledate='2008-01-01');
```

以下示例为包含 `saledate='2008-01-01'` 的分区设置新的 Amazon S3 路径。

```
alter table spectrum.sales_part
partition(saledate='2008-01-01')
set location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-01-01/';
```

以下示例将 `sales_date` 的名称更改为 `transaction_date`。

```
alter table spectrum.sales rename column sales_date to transaction_date;
```

以下示例将列映射设置为使用优化行列式 (ORC) 格式的外部表的位置映射。

```
alter table spectrum.orc_example
set table properties('orc.schema.resolution'='position');
```

以下示例将列映射设置为使用 ORC 格式的外部表的名称映射。

```
alter table spectrum.orc_example
set table properties('orc.schema.resolution'='name');
```

# ALTER TABLE ADD 和 DROP COLUMN 示例
<a name="r_ALTER_TABLE_COL_ex-add-drop"></a>

以下示例演示如何使用 ALTER TABLE 添加基本表列，然后删除该列；另外还演示如何删除具有从属对象的列。

## 添加基本列，然后删除该列
<a name="r_ALTER_TABLE_COL_ex-add-then-drop-a-basic-column"></a>

以下示例将独立 FEEDBACK\$1SCORE 列添加到 USERS 表。该列只包含一个整数，并且该列的默认值为 NULL（无反馈分数）。

首先，查询 PG\$1TABLE\$1DEF 目录表以查看 USERS 表的架构：

```
column        | type                   | encoding | distkey | sortkey
--------------+------------------------+----------+---------+--------
userid        | integer                | delta    | true    |       1
username      | character(8)           | lzo      | false   |       0
firstname     | character varying(30)  | text32k  | false   |       0
lastname      | character varying(30)  | text32k  | false   |       0
city          | character varying(30)  | text32k  | false   |       0
state         | character(2)           | bytedict | false   |       0
email         | character varying(100) | lzo      | false   |       0
phone         | character(14)          | lzo      | false   |       0
likesports    | boolean                | none     | false   |       0
liketheatre   | boolean                | none     | false   |       0
likeconcerts  | boolean                | none     | false   |       0
likejazz      | boolean                | none     | false   |       0
likeclassical | boolean                | none     | false   |       0
likeopera     | boolean                | none     | false   |       0
likerock      | boolean                | none     | false   |       0
likevegas     | boolean                | none     | false   |       0
likebroadway  | boolean                | none     | false   |       0
likemusicals  | boolean                | none     | false   |       0
```

现在添加 feedback\$1score 列：

```
alter table users
add column feedback_score int
default NULL;
```

从 USERS 中选择 FEEDBACK\$1SCORE 列以验证该列已添加：

```
select feedback_score from users limit 5;

feedback_score
----------------
NULL
NULL
NULL
NULL
NULL
```

删除该列以恢复原始 DDL：

```
alter table users drop column feedback_score;
```

## 删除具有从属对象的列
<a name="r_ALTER_TABLE_COL_ex-dropping-a-column-with-a-dependent-object"></a>

以下示例删除具有从属对象的列。结果是，同时删除从属对象。

开始时，将 FEEDBACK\$1SCORE 列重新添加到 USERS 表：

```
alter table users
add column feedback_score int
default NULL;
```

接下来，从名为 USERS\$1VIEW 的 USERS 表创建一个视图：

```
create view users_view as select * from users;
```

现在，尝试从 USERS 表中删除 FEEDBACK\$1SCORE 列。此 DROP 语句使用默认行为 (RESTRICT)：

```
alter table users drop column feedback_score;
```

Amazon Redshift 显示一条错误消息，说明由于另一个对象依赖该列而无法删除该列。

重新尝试删除 FEEDBACK\$1SCORE 列，这次指定 CASCADE 以删除所有从属对象：

```
alter table users
drop column feedback_score cascade;
```

# ALTER TABLE APPEND
<a name="r_ALTER_TABLE_APPEND"></a>

通过从现有的源表移动数据，将行附加到目标表。源表中的数据将移到目标表中的匹配列。列的顺序不重要。在成功将数据附加到目标表后，源表变成空表。由于是移动数据而不是复制数据，因此相比类似的 [CREATE TABLE AS](r_CREATE_TABLE_AS.md) 或 [INSERT](r_INSERT_30.md) INTO 操作，ALTER TABLE APPEND 通常要快得多。

**注意**  
ALTER TABLE APPEND 在源表和目标表之间移动数据块。为了提高性能，ALTER TABLE APPEND 不作为 append 操作的一部分压缩存储。因此，存储使用率会临时增加。要回收空间，请运行 [VACUUM](r_VACUUM_command.md) 操作。

同名的列还必须具有相同的列属性。如果源表包含目标表中不存在的列（反之亦然），请使用 IGNOREEXTRA 或 FILLTARGET 参数来指定如何管理额外的列。

您不能附加身份列。如果两个表中均包括身份列，则命令会失败。如果只有一个表具有标识列，请包含 FILLTARGET 或 IGNOREEXTRA 参数。有关更多信息，请参阅 [ALTER TABLE APPEND 使用说明](#r_ALTER_TABLE_APPEND_usage)。

您可以附加 GENERATED BY DEFAULT AS IDENTITY 列。您可以使用您提供的值来更新定义为 GENERATED BY DEFAULT AS IDENTITY 的列。有关更多信息，请参阅 [ALTER TABLE APPEND 使用说明](#r_ALTER_TABLE_APPEND_usage)。

目标表必须是永久表。但是，源可以是永久表，也可以是配置为流式摄取的实体化视图。如果一个对象定义了分配方式和分配键，则两个对象必须使用相同的分配方式和分配键。如果对对象进行排序，则两个对象必须使用相同的排序方式并定义相同的列作为排序键。

在操作完成之后，ALTER TABLE APPEND 会立即自动提交。该命令不能回滚。您不能在事务数据块 (BEGIN ... END) 中运行 ALTER TABLE APPEND。有关事务的更多信息，请参阅 [Amazon Redshift 中的隔离级别](c_serial_isolation.md)。

## 所需的权限
<a name="r_ALTER_TABLE_APPEND-privileges"></a>

根据具体的 ALTER TABLE APPEND 命令，需要以下权限之一：
+ Superuser
+ 具有 ALTER TABLE 系统权限的用户
+ 具有源表的 DELETE 和 SELECT 权限以及目标表的 INSERT 权限的用户

## 语法
<a name="r_ALTER_TABLE_APPEND-synopsis"></a>

```
ALTER TABLE target_table_name APPEND FROM [ source_table_name | source_materialized_view_name ]
[ IGNOREEXTRA | FILLTARGET ]
```

从实体化视图进行追加仅在实体化视图配置为[流式摄取到实体化视图](materialized-view-streaming-ingestion.md)的情形下才有效。

## 参数
<a name="r_ALTER_TABLE_APPEND-parameters"></a>

 *target\$1table\$1name*   
要将行附加到的表的名称。只指定表的名称，或者通过格式 *schema\$1name.table\$1name* 使用特定 schema。目标表必须是现有的永久表。

 FROM *source\$1table\$1name*   
提供要附加的行的表的名称。只指定表的名称，或者通过格式 *schema\$1name.table\$1name* 使用特定 schema。源表必须是现有的永久表。

 FROM *source\$1materialized\$1view\$1name*   
提供要附加的行的实体化视图的名称。从实体化视图进行追加仅在实体化视图配置为[流式摄取到实体化视图](materialized-view-streaming-ingestion.md)的情形下才有效。源实体化视图必须已经存在。

IGNOREEXTRA   
这个关键字指定，如果源表中包含目标表中不存在的列，则应该放弃额外列中的数据。您不能将 IGNOREEXTRA 与 FILLTARGET 配合使用。

FILLTARGET   
这个关键字指定，如果目标表中包含源表中不存在的列，则应该使用 [DEFAULT](r_CREATE_TABLE_NEW.md#create-table-default) 列值（如果已定义列值；否则使用 NULL 值）填充这些列。您不能将 IGNOREEXTRA 与 FILLTARGET 配合使用。

## ALTER TABLE APPEND 使用说明
<a name="r_ALTER_TABLE_APPEND_usage"></a>
+ ALTER TABLE APPEND 仅将相同列从源表移到目标表。列的顺序不重要。
+  如果源表或目标表包含额外的列，则根据以下规则使用 FILLTARGET 或 IGNOREEXTRA：
  + 如果源表包含目标表中不存在的列，则包含 IGNOREEXTRA。该命令会忽略源表中额外的列。
  + 如果目标表包含源表中不存在的列，则包含 FILLTARGET。该命令使用默认列值或 IDENTITY 值（如果已定义列值；否则使用 NULL 值）填充目标表中的额外列。
  + 如果源表和目标表均包含额外的列，则该命令失败。您不能同时使用 FILLTARGET 和 IGNOREEXTRA。
+ 如果两个表中的某个列具有相同名称，但具有不同的属性，则该命令失败。名称类似的列必须具有以下共同的属性：
  + 数据类型
  + 列大小
  + 压缩编码
  + 非 Null
  + 排序方式
  + 排序键列
  + 分配方式
  + 分配键列
+ 您不能附加身份列。如果源表和目标表中均具有身份列，则该命令失败。如果只有源表具有身份列，则包含 IGNOREEXTRA 参数以忽略身份列。如果只有目标表具有身份列，则包含 FILLTARGET 参数，以便根据为该表定义的 IDENTITY 子句来填充身份列。有关更多信息，请参阅 [DEFAULT](r_CREATE_TABLE_NEW.md#create-table-default)。
+ 您可以使用 ALTER TABLE APPEND 语句附加默认身份列。有关更多信息，请参阅 [CREATE TABLE](r_CREATE_TABLE_NEW.md)。
+ ALTER TABLE APPEND 操作在连接到以下任何一项的 Amazon Redshift 流式传输实体化视图上运行时，将持有排他锁：
  +  Amazon Kinesis 数据流 
  +  Amazon Managed Streaming for Apache Kafka 主题 
  +  支持的外部流，例如 Confluent Cloud Kafka 主题 

  有关更多信息，请参阅 [流式摄取到实体化视图](materialized-view-streaming-ingestion.md)。

## ALTER TABLE APPEND 示例
<a name="r_ALTER_TABLE_APPEND_examples"></a>

假设您的组织维护表 SALES\$1MONTHLY 来获取当前销售交易。您希望每个月将数据从交易表移动到 SALES 表。

您可以使用下面的 INSERT INTO 和 TRUNCATE 命令来完成任务。

```
insert into sales (select * from sales_monthly);
truncate sales_monthly;
```

不过，您可以使用 ALTER TABLE APPEND 命令执行相同的操作，而且效率要高得多。

首先，查询 [PG\$1TABLE\$1DEF](r_PG_TABLE_DEF.md) 系统目录表，验证两个表中包含具有相同列属性的相同列。

```
select trim(tablename) as table, "column", trim(type) as type,
encoding, distkey, sortkey, "notnull"
from pg_table_def where tablename like 'sales%';

table      | column     | type                        | encoding | distkey | sortkey | notnull
-----------+------------+-----------------------------+----------+---------+---------+--------
sales      | salesid    | integer                     | lzo      | false   |       0 | true
sales      | listid     | integer                     | none     | true    |       1 | true
sales      | sellerid   | integer                     | none     | false   |       2 | true
sales      | buyerid    | integer                     | lzo      | false   |       0 | true
sales      | eventid    | integer                     | mostly16 | false   |       0 | true
sales      | dateid     | smallint                    | lzo      | false   |       0 | true
sales      | qtysold    | smallint                    | mostly8  | false   |       0 | true
sales      | pricepaid  | numeric(8,2)                | delta32k | false   |       0 | false
sales      | commission | numeric(8,2)                | delta32k | false   |       0 | false
sales      | saletime   | timestamp without time zone | lzo      | false   |       0 | false
salesmonth | salesid    | integer                     | lzo      | false   |       0 | true
salesmonth | listid     | integer                     | none     | true    |       1 | true
salesmonth | sellerid   | integer                     | none     | false   |       2 | true
salesmonth | buyerid    | integer                     | lzo      | false   |       0 | true
salesmonth | eventid    | integer                     | mostly16 | false   |       0 | true
salesmonth | dateid     | smallint                    | lzo      | false   |       0 | true
salesmonth | qtysold    | smallint                    | mostly8  | false   |       0 | true
salesmonth | pricepaid  | numeric(8,2)                | delta32k | false   |       0 | false
salesmonth | commission | numeric(8,2)                | delta32k | false   |       0 | false
salesmonth | saletime   | timestamp without time zone | lzo      | false   |       0 | false
```

接下来，查看每个表的大小。

```
select count(*) from sales_monthly;
 count
-------
  2000
(1 row)

select count(*) from sales;
 count
-------
 412,214
(1 row)
```

现在运行以下 ALTER TABLE APPEND 命令。

```
alter table sales append from sales_monthly;         
```

再次查看每个表的大小。SALES\$1MONTHLY 表现在包含 0 行；而 SALES 表增长了 2000 行。

```
select count(*) from sales_monthly;
 count
-------
     0
(1 row)

select count(*) from sales;
 count
-------
 414214
(1 row)
```

如果源表中的列多于目标表，请指定 IGNOREEXTRA 参数。以下示例使用 IGNOREEXTRA 参数，这样在附加到 SALES 表时，会忽略 SALES\$1LISTING 表中的额外列。

```
alter table sales append from sales_listing ignoreextra;
```

如果目标表中的列多于源表，请指定 FILLTARGET 参数。以下示例使用 FILLTARGET 参数，以填充 SALES\$1REPORT 表中存在而 SALES\$1MONTH 表中不存在的列。

```
alter table sales_report append from sales_month filltarget;
```

以下示例显示了在实体化视图作为源的情况下如何使用 ALTER TABLE APPEND 的示例。

```
ALTER TABLE target_tbl APPEND FROM my_streaming_materialized_view;
```

此示例中的表和实体化视图名称是示例。从实体化视图进行追加仅在实体化视图配置为[流式摄取到实体化视图](materialized-view-streaming-ingestion.md)的情形下才有效。它将源实体化视图中的所有记录移动到与实体化视图具有相同架构的目标表中，并保持实体化视图不变。这与数据来源为表时的行为相同。

# ALTER TEMPLATE
<a name="r_ALTER_TEMPLATE"></a>

更改现有模板的定义。使用此命令可重命名模板、更改模板的所有者、在模板定义中添加或移除参数，或设置参数值。

## 所需的权限
<a name="r_ALTER_TEMPLATE-privileges"></a>

要更改模板，您必须拥有以下其中一项：
+ 超级用户权限
+ 对包含模板的架构的 ALTER TEMPLATE 权限和 USAGE 权限

## 语法
<a name="r_ALTER_TEMPLATE-synopsis"></a>

```
ALTER TEMPLATE [database_name.][schema_name.]template_name
{
RENAME TO new_name
| OWNER TO new_owner
| ADD  parameter [AS] [value]
| DROP parameter
| SET parameter TO value1 [, parameter2 TO value2 , ...]
};
```

## 参数
<a name="r_ALTER_TEMPLATE-parameters"></a>

 *database\$1name*   
（可选）在其中创建模板的数据库的名称。如果未指定，则使用当前数据库。

 *schema\$1name*   
（可选）在其中创建模板的架构的名称。如果未指定，则在当前搜索路径中搜索模板。

 *template\$1name*   
要更改的模板的名称。

RENAME TO   
用于重命名模板的子句。

 *new\$1name*   
模板的新名称。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。

OWNER TO   
用于更改模板所有者的子句。

 *new\$1owner*   
模板的新所有者。

ADD *parameter* [AS] [*value*]  
将新参数添加到模板。  
+ 对于仅限关键字的参数（例如 CSV 或 GZIP），请仅指定参数名称。
+ 对于需要值的参数，请指定参数名称，且后跟值。您可以选择在参数和值之间包含 AS。

DROP *parameter*  
从模板中移除指定的参数。无法使用单个 DROP 命令删除多个参数。

SET *parameter* TO *value1* [, *parameter2* TO *value2* , ...]  
更新现有模板参数的值。仅用于已具有值的参数。可以在单个命令中更新多个参数。

## 示例
<a name="r_ALTER_TEMPLATE-examples"></a>

以下示例将 test\$1template 模板重命名为 demo\$1template。

```
ALTER TEMPLATE test_template
RENAME TO demo_template;
```

以下示例将 demo\$1template 架构的所有权授予用户 bob。

```
ALTER TEMPLATE demo_template
OWNER TO bob;
```

以下示例向模板 demo\$1template 添加参数 `CSV`

```
ALTER TEMPLATE demo_template
ADD CSV;
```

以下示例向模板 demo\$1template 添加参数 `TIMEFORMAT 'auto'`

```
ALTER TEMPLATE demo_template
ADD TIMEFORMAT 'auto';
```

以下示例从模板 demo\$1template 中删除参数 `ENCRYPTED`

```
ALTER TEMPLATE demo_template
DROP ENCRYPTED;
```

以下示例将 `DELIMITER` 参数设置为 `'|'`，并将 `TIMEFORMAT` 参数设置为 `'epochsecs'`：

```
ALTER TEMPLATE demo_template
SET DELIMITER TO '|', TIMEFORMAT TO 'epochsecs';
```

# ALTER USER
<a name="r_ALTER_USER"></a>

更改数据库用户。

## 所需的权限
<a name="r_ALTER_USER-privileges"></a>

以下是 ALTER USER 所需的权限：
+ Superuser
+ 具有 ALTER USER 权限的用户
+ 想更改自己密码的当前用户

## 语法
<a name="r_ALTER_USER-synopsis"></a>

```
ALTER USER username [ WITH ] option [, ... ]

where option is

CREATEDB | NOCREATEDB
| CREATEUSER | NOCREATEUSER
| SYSLOG ACCESS { RESTRICTED | UNRESTRICTED }
| PASSWORD { 'password' | 'md5hash' | 'sha256hash' | DISABLE }
[ VALID UNTIL 'expiration_date' ]
| RENAME TO new_name |
| CONNECTION LIMIT { limit | UNLIMITED }
| SESSION TIMEOUT limit | RESET SESSION TIMEOUT
| SET parameter { TO | = } { value | DEFAULT }
| RESET parameter
| EXTERNALID external_id
```

## 参数
<a name="r_ALTER_USER-parameters"></a>

 *username*   
用户的名称。

WITH   
可选关键字。

CREATEDB \$1 NOCREATEDB   
CREATEDB 选项允许用户创建新数据库。NOCREATEDB 是默认值。

CREATEUSER \$1 NOCREATEUSER   
使用 CREATEUSER 选项可以创建具备所有数据库权限的超级用户，包括 CREATE USER。默认值为 NOCREATEUSER。有关更多信息，请参阅 [超级用户](r_superusers.md)。

SYSLOG ACCESS \$1 RESTRICTED \$1 UNRESTRICTED \$1  <a name="alter-user-syslog-access"></a>
一个子句，它指定用户必须对 Amazon Redshift 系统表和视图具有的访问级别。  
拥有 SYSLOG ACCESS RESTRICTED 权限的普通用户在用户可见的系统表和视图中只能查看该用户生成的行。默认值为 RESTRICTED。  
拥有 SYSLOG ACCESS UNRESTRICTED 权限的普通用户可以查看用户可见的系统表和视图中的所有行，包括其他用户生成的行。UNRESTRICTED 不向普通用户授予对超级用户可见的表的访问权限。只有超级用户可以查看超级用户可见的表。  
如果向用户授予对系统表的无限制访问权限，用户便可以看到由其他用户生成的数据。例如，STL\$1QUERY 和 STL\$1QUERYTEXT 包含 INSERT、UPDATE 和 DELETE 语句的完整文本（其中可能包含敏感的用户生成数据）。
SVV\$1TRANSACTIONS 中的所有行都对所有用户可见。  
有关更多信息，请参阅 [系统表和视图中的数据可见性](cm_chap_system-tables.md#c_visibility-of-data)。

PASSWORD \$1 '*password*' \$1 '*md5hash*' \$1 '*sha256hash*' \$1 DISABLE \$1  
设置用户的密码。  
默认情况下，用户可以更改自己的密码，除非密码被禁用。要禁用用户的密码，请指定 DISABLE。禁用某个用户的密码后，将从系统中删除该密码，而此用户只能使用临时 AWS Identity and Access Management (IAM) 用户凭证进行登录。有关更多信息，请参阅[使用 IAM 身份验证生成数据库用户凭证](https://docs.aws.amazon.com/redshift/latest/mgmt/generating-user-credentials.html)。只有超级用户才能启用或禁用密码。您不能禁用超级用户的密码。要启用密码，请运行 ALTER USER 并指定密码。  
有关使用 PASSWORD 参数的详细信息，请参阅[CREATE USER](r_CREATE_USER.md)。

VALID UNTIL '*expiration\$1date*'  
指定密码具有过期日期。使用值 `'infinity'` 可避免密码具有过期日期。此参数的有效数据类型为时间戳。  
只有超级用户才能使用此参数。

RENAME TO   
重命名用户。

 *new\$1name*   
用户的新名称。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。  
在重命名用户时，还必须重置用户的密码。重置密码不必与之前的密码不同。用户名用作密码加密的一部分，因此在重命名用户时，将会清除密码。用户将无法登录，直至重置密码。例如：  

```
alter user newuser password 'EXAMPLENewPassword11'; 
```

CONNECTION LIMIT \$1 *limit* \$1 UNLIMITED \$1   
允许用户同时打开的数据库连接的最大数量。此限制不适用于超级用户。使用 UNLIMITED 关键字设置允许的并行连接的最大数量。对每个数据库的连接数量可能也会施加限制。有关更多信息，请参阅 [CREATE DATABASE](r_CREATE_DATABASE.md)。默认为 UNLIMITED。要查看当前连接，请查询 [STV\$1SESSIONS](r_STV_SESSIONS.md) 系统视图。  
如果用户及数据库连接限制均适用，当用户尝试连接时，必须有一个同时低于这两个限制的未使用的连接槽可用。

SESSION TIMEOUT *limit* \$1 RESET SESSION TIMEOUT  
会话保持非活动或空闲状态的最长时间（秒）。范围在 60 秒（1 分钟）到 1,728,000 秒（20 天）之间。如果没有为用户设置会话超时，则应用集群设置。有关更多信息，请参阅《Amazon Redshift 管理指南》**中的 [Amazon Redshift 中的配额和限制](https://docs.aws.amazon.com/redshift/latest/mgmt/amazon-redshift-limits.html)。  
设置会话超时时，它仅应用于新会话。  
要查看有关活动用户会话的信息，包括开始时间、用户名和会话超时，请查询 [STV\$1SESSIONS](r_STV_SESSIONS.md) 系统视图。要查看有关用户会话历史记录的信息，请查询 [STL\$1SESSIONS](r_STL_SESSIONS.md) 视图。要检索有关数据库用户的信息（包括会话超时值），请查询 [SVL\$1USER\$1INFO](r_SVL_USER_INFO.md) 视图。

SET   
针对指定用户运行的所有会话，将某个配置参数设置为新的默认值。

RESET   
为指定用户将某个配置参数重置为原始默认值。

 *参数*   
要设置或重置的参数的名称。

 *值*   
参数的新值。

DEFAULT   
针对指定用户运行的所有会话，将配置参数设置为默认值。

EXTERNALID *external\$1id*   
用户的标识符，与身份提供者关联。用户必须已禁用密码。有关更多信息，请参阅 [Amazon Redshift 的原生身份提供者 (IdP) 联合身份验证](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-native-idp.html)。

## 使用说明
<a name="r_ALTER_USER_usage_notes"></a>
+ **尝试更改 rdsdb** - 您无法更改名为 `rdsdb` 的用户。
+ **创建未知密码** – 使用 AWS Identity and Access Management (IAM) 身份验证创建数据库用户凭证时，您可能希望创建仅使用临时凭证便可以登录的超级用户。您不能禁用超级用户的密码，但可以使用随机生成的 MD5 哈希字符串创建一个未知密码。

  ```
  alter user iam_superuser password 'md51234567890123456780123456789012';
  ```
+ **设置 search\$1path** – 当您使用 ALTER USER 命令设置 [search\$1path](r_search_path.md) 参数时，所做修改将在指定的用户下次登录时生效。如果您希望更改当前用户和会话的 search\$1path 值，请使用 SET 命令。
+ **设置时区** – 当您将 SET TIMEZONE 与 ALTER USER 命令一起使用时，所做修改将在指定的用户下次登录时生效。
+ **使用动态数据掩蔽和行级安全策略** – 当您的预调配集群或无服务器命名空间具有任何动态数据掩蔽或行级安全策略时，普通用户将无法使用以下命令：

  ```
  ALTER <current_user> SET enable_case_sensitive_super_attribute/enable_case_sensitive_identifier/downcase_delimited_identifier
  ```

  只有超级用户和具有 ALTER USER 权限的用户才能设置这些配置选项。有关行级别安全性的信息，请参阅[行级别安全性](t_rls.md)。有关动态数据掩蔽的信息，请参阅[动态数据掩蔽](t_ddm.md)。

## 示例
<a name="r_ALTER_USER-examples"></a>

以下示例为用户 ADMIN 授予创建数据库的权限：

```
alter user admin createdb;
```

以下示例将用户 ADMIN 的密码设置为 `adminPass9`，并为密码设置一个到期日期和时间：

```
alter user admin password 'adminPass9'
valid until '2017-12-31 23:59';
```

以下示例将用户 ADMIN 重命名为 SYSADMIN：

```
alter user admin rename to sysadmin;
```

以下示例将用户的空闲会话超时更新为 300 秒。

```
ALTER USER dbuser SESSION TIMEOUT 300;
```

重置用户的空闲会话超时。重置它时，将应用集群设置。您必须是数据库超级用户才能执行此命令。有关更多信息，请参阅《Amazon Redshift 管理指南》**中的 [Amazon Redshift 中的配额和限制](https://docs.aws.amazon.com/redshift/latest/mgmt/amazon-redshift-limits.html)。

```
ALTER USER dbuser RESET SESSION TIMEOUT;
```

以下示例更新名为 `bob` 的用户的外部 ID。命名空间为 `myco_aad`。如果命名空间与注册的身份提供者没有关联，则会导致错误。

```
ALTER USER myco_aad:bob EXTERNALID "ABC123" PASSWORD DISABLE;
```

以下示例为某个特定数据库用户运行的所有会话设置时区。该示例更改后续会话的时区，而不是更改当前会话的时区。

```
ALTER USER odie SET TIMEZONE TO 'Europe/Zurich';
```

以下示例设置了允许用户 `bob` 打开的最大数据库连接数。

```
ALTER USER bob CONNECTION LIMIT 10;
```

# ANALYZE
<a name="r_ANALYZE"></a>

更新表统计数据以供查询计划程序使用。

## 所需的权限
<a name="r_ANALYZE-privileges"></a>

以下是 ANALYZE 所需的权限：
+ Superuser
+ 具有 ANALYZE 权限的用户
+ 关系的拥有者
+ 向其共享表的数据库拥有者

## 语法
<a name="r_ANALYZE-synopsis"></a>

```
ANALYZE [ VERBOSE ]
[ [ table_name [ ( column_name [, ...] ) ] ]
[ PREDICATE COLUMNS | ALL  COLUMNS ]
```

## 参数
<a name="r_ANALYZE-parameters"></a>

VERBOSE   
返回有关 ANALYZE 操作的进度信息消息的子句。在不指定表时，此选项会非常有用。

 *table\$1name*   
您可以分析特定表，包括临时表。您可以通过其 schema 名称来限定表。您可以视需要指定 table\$1name 来分析单个表。您不能在单个 *ANALYZE table\$1name* 语句中指定多个 *table\$1name*。如果您不指定 *table\$1name* 值，则将分析当前连接的数据库中的所有表，包括系统目录中的持久性表。如果自上次执行 ANALYZE 以来更改的行数百分比低于分析阈值，Amazon Redshift 将跳过对表的分析。有关更多信息，请参阅 [分析阈值](#r_ANALYZE-threshold)。  
您不需要分析 Amazon Redshift 系统表（STL 和 STV 表）。

 *column\$1name*   
如果您指定 *table\$1name*，您还可以指定表中的一个或多个列（以两旁加括号的逗号分隔列表的形式）。如果指定了列列表，则只分析列出的列。

 PREDICATE COLUMNS \$1 ALL COLUMNS   
用于指示 ANALYZE 是否应仅包含谓词列的子句。指定 PREDICATE COLUMNS 以仅分析在以前查询中用作谓词的列或可能用作谓词的候选列。指定 ALL COLUMNS 将分析所有列。默认值为 ALL COLUMNS。  
如果以下任意一项为 true，则列包括在一组谓词列中。  
+ 该列已在查询中用作筛选条件、联接条件或 group by 子句的一部分。
+ 该列为分配键。
+ 该列为排序键的一部分。
如果未将任何列标记为谓词列（例如，由于尚未查询表），则即使指定了 PREDICATE COLUMNS，也仍将分析所有列。发生这种情况时，Amazon Redshift 可能会回复一条消息，例如，对于“*table-name*”找不到谓词列。请分析所有列。有关谓词列的更多信息，请参阅[分析表](t_Analyzing_tables.md)。

## 使用说明
<a name="r_ANALYZE-usage-notes"></a>

Amazon Redshift 自动对使用以下命令创建的表运行 ANALYZE：
+ CREATE TABLE AS
+ CREATE TEMP TABLE AS 
+ SELECT INTO

 您无法分析外部表。

在最初创建这些表时，您不需要对这些表运行 ANALYZE 命令。如果修改了这些表，则应通过用来分析其他表的方式来分析这些表。

### 分析阈值
<a name="r_ANALYZE-threshold"></a>

为了减少处理时间并提高整体系统性能，在自上次运行 ANALYZE 命令以来更改的行数百分比低于 [analyze\$1threshold\$1percent](r_analyze_threshold_percent.md) 参数所指定分析阈值的情况下，Amazon Redshift 将跳过对表执行的 ANALYZE 操作。默认情况下，`analyze_threshold_percent` 为 10。要更改当前会话的 `analyze_threshold_percent`，请执行 [SET](r_SET.md) 命令。以下示例将 `analyze_threshold_percent` 更改为 20%。

```
set analyze_threshold_percent to 20;
```

要在仅有少量行发生更改时对表进行分析，请将 `analyze_threshold_percent` 设置为任意较小的数字。例如，如果您将 `analyze_threshold_percent` 设置为 0.01，则在含有 100000000 行的表中至少有 10000 行发生更改时，不会跳过该表。

```
set analyze_threshold_percent to 0.01;
```

如果 ANALYZE 因未达到分析阈值而跳过表，Amazon Redshift 将返回以下消息。

```
ANALYZE SKIP
```

要在即使没有任何行发生更改时仍对所有表进行分析，请将 `analyze_threshold_percent` 设置为 0。

要查看 ANALYZE 操作的结果，请查询 [STL\$1ANALYZE](r_STL_ANALYZE.md) 系统表。

有关分析表的更多信息，请参阅[分析表](t_Analyzing_tables.md)。

## 示例
<a name="r_ANALYZE-examples"></a>

分析 TICKIT 数据库中的所有表，并返回进度信息。

```
analyze verbose;
```

只分析 LISTING 表。

```
analyze listing;
```

分析 VENUE 表中的 VENUEID 和 VENUENAME 列。

```
analyze venue(venueid, venuename);
```

仅分析 VENUE 表中的谓词列。

```
analyze venue predicate columns;
```

# ANALYZE COMPRESSION
<a name="r_ANALYZE_COMPRESSION"></a>

执行压缩分析，并针对所分析的表使用建议的压缩编码生成报告。报告会针对每一列估计与原始编码相比磁盘空间的潜在压缩量。

## 语法
<a name="r_ANALYZE_COMPRESSION-synopsis"></a>

```
ANALYZE COMPRESSION
[ [ table_name ]
[ ( column_name [, ...] ) ] ]
[COMPROWS numrows]
```

## 参数
<a name="r_ANALYZE_COMPRESSION-parameters"></a>

 *table\$1name*   
您可以分析特定表的压缩，包括临时表。您可以通过其 schema 名称来限定表。您可以视需要指定 *table\$1name* 来分析单个表。如果您不指定 *table\$1name*，则将分析当前连接的数据库中的所有表。您不能在单个 ANALYZE COMPRESSION 语句中指定多个 *table\$1name*。

 *column\$1name*   
如果您指定 *table\$1name*，您还可以指定表中的一个或多个列（以两旁加括号的逗号分隔列表的形式）。

COMPROWS  
要在压缩分析中用作采样大小的行数。将对来自每个数据切片的行运行分析。例如，如果您指定 COMPROWS 1000000 (1000000)，而系统共包含 4 个切片，则每个切片将读取和分析 250000 行。如果未指定 COMPROWS，则采样大小默认为每个切片 100000 行。如果 COMPROWS 值小于每个切片 100000 行的默认值，则会自动将该值升级到默认值。但是，如果表中的数据量不足，无法得到有意义的样本，则压缩分析将不会生成建议。如果 COMPROWS 数字大于表中的行数，则 ANALYZE COMPRESSION 命令仍会针对所有可用行继续运行压缩分析。如果未指定表，则使用 COMPROWS 会导致错误。

 *numrows*   
要在压缩分析中用作采样大小的行数。*numrows* 的可接受范围为 1000 到 1000000000 (1,000,000,000) 之间的数字。

## 使用说明
<a name="r_ANALYZE_COMPRESSION_usage_notes"></a>

ANALYZE COMPRESSION 获取独占的表锁定，从而阻止对表的并发读写。只在表空闲时运行 ANALYZE COMPRESSION 命令。

运行 ANALYZE COMPRESSION 以根据表内容的采样来获取列编码方案的建议。ANALYZE COMPRESSION 是一个建议工具，不会修改表的列编码。可以通过重新创建表或使用相同 schema 创建新表来应用推荐的编码。使用适当的编码方案重新创建未压缩的表可以显著降低其磁盘上的大小。此方法可节省磁盘空间并改善 I/O 密集型工作负载的查询性能。

ANALYZE COMPRESSION 会跳过实际分析阶段，并直接返回指定为 SORTKEY 的任何列上的原始编码类型。之所以会执行此操作，是因为当 SORTKEY 列的压缩率远高于其他列时，范围受限扫描的执行效果可能会很差。

## 示例
<a name="r_ANALYZE_COMPRESSION-examples"></a>

以下示例说明了仅 LISTING 表中列的编码和预计减少的百分比：

```
analyze compression listing;
  
  Table  |     Column     | Encoding | Est_reduction_pct 
---------+----------------+----------+-------------------
 listing | listid         | az64     | 40.96
 listing | sellerid       | az64     | 46.92
 listing | eventid        | az64     | 53.37
 listing | dateid         | raw      | 0.00
 listing | numtickets     | az64     | 65.66
 listing | priceperticket | az64     | 72.94
 listing | totalprice     | az64     | 68.05
 listing | listtime       | az64     | 49.74
```

以下示例分析了 SALES 表中的 QTYSOLD、COMMISSION 和 SALETIME 列。

```
analyze compression sales(qtysold, commission, saletime);

 Table |   Column   | Encoding | Est_reduction_pct 
-------+------------+----------+-------------------
 sales | salesid    | N/A      | 0.00
 sales | listid     | N/A      | 0.00
 sales | sellerid   | N/A      | 0.00
 sales | buyerid    | N/A      | 0.00
 sales | eventid    | N/A      | 0.00
 sales | dateid     | N/A      | 0.00
 sales | qtysold    | az64     | 83.06
 sales | pricepaid  | N/A      | 0.00
 sales | commission | az64     | 71.85
 sales | saletime   | az64     | 49.63
```

# ATTACH MASKING POLICY
<a name="r_ATTACH_MASKING_POLICY"></a>

将现有动态数据掩蔽策略附加到列。有关动态数据掩蔽的更多信息，请参阅 [动态数据掩蔽](t_ddm.md)。

超级用户和具有 sys:secadmin 角色的用户或角色可以附加屏蔽策略。

## 语法
<a name="r_ATTACH_MASKING_POLICY-synopsis"></a>

```
ATTACH MASKING POLICY 
{
  policy_name ON relation_name
  | database_name.policy_name ON database_name.schema_name.relation_name
}
( { output_column_names | output_path } )
[ USING ( { input_column_names | input_path } ) ]
TO { user_name | ROLE role_name | PUBLIC }
[ PRIORITY priority ];
```

## 参数
<a name="r_ATTACH_MASKING_POLICY-parameters"></a>

*policy\$1name*   
要附加的屏蔽策略的名称。

database\$1name  
在其中创建策略和关系的数据库的名称。策略和关系必须在同一个数据库中。该数据库可以是连接的数据库，也可以是支持 Amazon Redshift 联合身份验证权限的数据库。

schema\$1name  
关系所属的架构的名称。

 *relation\$1name*   
要将掩蔽策略附加到的关系的名称。

*output\$1column\$1names*   
将要应用屏蔽策略的列的名称。

*output\$1paths*   
掩蔽策略将应用于的 SUPER 对象的完整路径，包括列名。例如，对于具有名为 `person` 的 SUPER 类型列的关系，*output\$1path* 可能为 `person.name.first_name`。

*input\$1column\$1names*   
将用作屏蔽策略输入的列的名称。此参数为可选的。如果未指定，则掩蔽策略使用 *output\$1column\$1names* 作为输入。

*input\$1paths*   
将用作掩蔽策略输入的 SUPER 对象的完整路径。此参数为可选的。如果未指定，则掩蔽策略使用 *output\$1path* 作为输入。

*user\$1name*   
要附加屏蔽策略的用户的名称。您不能将两个策略附加到用户和列或角色和列的相同组合。您可以将一个策略附加到用户，将另一个策略附加到该用户的角色。在这种情况下，优先级较高的策略适用。  
在单个 ATTACH MASKING POLICY 命令中，您只能设置 user\$1name、role\$1name 和 PUBLIC 中的一项。

*role\$1name*   
要附加屏蔽策略的角色的名称。您不能将两个策略附加到同一个列/角色对。您可以将一个策略附加到用户，将另一个策略附加到该用户的角色。在这种情况下，优先级较高的策略适用。  
在单个 ATTACH MASKING POLICY 命令中，您只能设置 user\$1name、role\$1name 和 PUBLIC 中的一项。

*PUBLIC*   
将屏蔽策略附加到访问表的所有用户。您必须为附加到特定列/用户或列/角色对的其他屏蔽策略分配比 PUBLIC 策略更高的优先级，这样才能让这些策略适用。  
在单个 ATTACH MASKING POLICY 命令中，您只能设置 user\$1name、role\$1name 和 PUBLIC 中的一项。

*priority*   
屏蔽策略的优先级。当多个屏蔽策略应用于给定用户的查询时，具有最高优先级的策略适用。  
不能将两个不同的策略以相同的优先级附加到同一列上，即使这两个策略附加到了不同的用户或角色。您可以多次将相同的策略附加到同一组表、输出列、输入列和优先级参数，只要每次附加策略的用户或角色不同即可。  
即使两个策略适用于不同的角色，您也无法将一个策略应用于与该列中附加的另一个策略具有相同优先级的列。该字段是可选的。如果未指定优先级，则屏蔽策略默认为优先级为 0。

有关在 Amazon Redshift 联合身份验证权限目录上使用 ATTACH MASKING POLICY 的信息，请参阅[使用 Amazon Redshift 联合身份验证权限管理访问控制](https://docs.aws.amazon.com/redshift/latest/dg/federated-permissions-managing-access.html)。

# ATTACH RLS POLICY
<a name="r_ATTACH_RLS_POLICY"></a>

将表上的行级别安全性策略附加到一个或多个用户或角色。

超级用户和具有 `sys:secadmin` 角色的用户或角色可以附加策略。

## 语法
<a name="r_ATTACH_RLS_POLICY-synopsis"></a>

```
ATTACH RLS POLICY 
{
  policy_name ON [TABLE] table_name [, ...]
  | database_name.policy_name ON [TABLE] database_name.schema_name.table_name [, ...]
}
TO { user_name | ROLE role_name | PUBLIC } [, ...]
```

## 参数
<a name="r_ATTACH_RLS_POLICY-parameters"></a>

 *policy\$1name*   
策略的名称。

database\$1name  
在其中创建策略和关系的数据库的名称。策略和关系必须在同一个数据库中。该数据库可以是连接的数据库，也可以是支持 Amazon Redshift 联合身份验证权限的数据库。

schema\$1name  
关系所属的架构的名称。

table\$1name  
行级安全策略所附加到的关系。

TO \$1 *user\$1name* \$1 ROLE *role\$1name* \$1 PUBLIC\$1 [, ...]  
指定是否将策略附加到一个或多个指定用户或角色。

有关在 Amazon Redshift 联合身份验证权限目录上使用 ATTACH RLS POLICY 的信息，请参阅[使用 Amazon Redshift 联合身份验证权限管理访问控制](https://docs.aws.amazon.com/redshift/latest/dg/federated-permissions-managing-access.html)。

## 使用说明
<a name="r_ATTACH_RLS_POLICY-usage"></a>

在使用 ATTACH RLS POLICY 语句时，请遵守以下规则：
+ 附加的表应该包含策略创建语句的 WITH 子句中列出的所有列。
+ Amazon Redshift RLS 支持将 RLS 策略附加到以下对象：
  +  表 
  +  视图
  +  后期绑定视图 
  +  实体化视图
+ Amazon Redshift RLS 不支持将 RLS 策略附加到以下对象：
  +  目录表 
  +  跨数据库关系 
  +  外部表 
  +  临时表 
  +  策略查找表
  + 实体化视图基表
+ 附加到超级用户或具有 `sys:secadmin` 权限的用户的 RLS 策略将被忽略。

## 示例
<a name="r_ATTACH_RLS_POLICY-examples"></a>

以下示例将 RLS 策略附加到指定的表和角色组合。当角色为 `analyst` 或 `dbadmin` 的任何用户访问 tickit\$1category\$1redshift 表时，RLS 策略适用于此类用户。

```
ATTACH RLS POLICY policy_concerts ON tickit_category_redshift TO ROLE analyst, ROLE dbadmin;
```

# BEGIN
<a name="r_BEGIN"></a>

开始事务。与 START TRANSACTION 同义。

事务是单一的逻辑工作单元，而无论是包含一个命令还是多个命令。一般来说，事务中的所有命令都是在数据库的快照上执行，其开始时间由为 `transaction_snapshot_begin` 系统配置参数设置的值决定。

预设情况下，单独的 Amazon Redshift 操作（查询、DDL 语句、加载）自动提交到数据库。如果要暂停操作提交直到后续工作完成，您需要使用 BEGIN 语句打开一个事务，然后运行所需的命令，最后使用 [COMMIT](r_COMMIT.md) 或 [END](r_END.md) 语句关闭事务。如果需要，您可以使用 [ROLLBACK](r_ROLLBACK.md) 语句停止正在进行的事务。此行为的一个例外是 [TRUNCATE](r_TRUNCATE.md) 命令，它在所运行的事务中提交事务，并且无法回滚。

## 语法
<a name="r_BEGIN-synopsis"></a>

```
BEGIN [ WORK | TRANSACTION ] [ ISOLATION LEVEL option ] [ READ WRITE | READ ONLY ]

START TRANSACTION [ ISOLATION LEVEL option ] [ READ WRITE | READ ONLY ]

Where option is

SERIALIZABLE
| READ UNCOMMITTED
| READ COMMITTED
| REPEATABLE READ

Note: READ UNCOMMITTED, READ COMMITTED, and REPEATABLE READ have no
operational impact and map to SERIALIZABLE in Amazon Redshift. You can see database isolation levels on your cluster 
by querying the stv_db_isolation_level table.
```

## 参数
<a name="r_BEGIN-parameters"></a>

WORK   
可选关键字。

TRANSACTION   
可选关键字；WORK 和 TRANSACTION 同义。

ISOLATION LEVEL SERIALIZABLE   
默认情况下支持可序列化隔离，因此无论此语法是否包含在语句中，事务的行为都是相同的。有关更多信息，请参阅 [管理并发写入操作](c_Concurrent_writes.md)。不支持任何其他隔离级别。  
SQL 标准定义了四个事务隔离级别，可防止*脏读*（事务读取并发未提交事务写入的数据）、*不可重复读*（事务重新读取之前已读取的数据，并发现自初始读取以后，另一个已提交的事务已更改了该数据）以及*幻读*（事务重新运行查询，返回满足一组搜索条件的行，然后发现这组行由于另一个最近提交的事务而发生了更改）：  
+ 读取未提交：脏读、不可重复读以及幻读是可能的。
+ 读取已提交：不可重复读和幻读是可能的。
+ 可重复读：幻读是可能的。
+ 可序列化：阻止脏读、不可重复读以及幻读。
虽然您可以使用这四个事务隔离级别中的任意一个，不过 Amazon Redshift 会将所有隔离级别作为可序列化级别处理。

READ WRITE   
向事务提供读取和写入权限。

READ ONLY   
向事务提供只读权限。

## 示例
<a name="r_BEGIN-examples"></a>

以下示例开始一个可序列化事务块：

```
begin;
```

以下示例开始一个具有可序列化隔离级别和读写权限的事务块：

```
begin read write;
```

# CALL
<a name="r_CALL_procedure"></a>

运行存储过程。CALL 命令必须包括过程名称和输入参数值。您必须使用 CALL 语句调用存储过程。

**注意**  
CALL 不能成为任何常规查询的一部分。

## 语法
<a name="r_CALL_procedure-synopsis"></a>

```
CALL sp_name ( [ argument ] [, ...] )
```

## 参数
<a name="r_CALL_procedure-parameters"></a>

 *sp\$1name*   
要运行的过程的名称。

 *argument*   
输入参数的值。此参数也可以是函数名称，例如 `pg_last_query_id()`。您不能将查询用作 CALL 参数。

## 使用说明
<a name="r_CALL_procedure-usage-notes"></a>

Amazon Redshift 存储过程支持嵌套和递归调用，如下所述。此外，请确保您的驱动程序支持是最新的，如下所述

**Topics**
+ [嵌套调用](#r_CALL_procedure-nested-calls)
+ [驱动程序支持](#r_CALL_procedure-driver-support)

### 嵌套调用
<a name="r_CALL_procedure-nested-calls"></a>

Amazon Redshift 存储过程支持嵌套和递归调用。允许的最大嵌套级别数为 16。嵌套调用可以将业务逻辑封装到较小的过程中，这些过程可以由多个调用者共享。

如果调用了具有输出参数的嵌套过程，则该内部过程必须定义 INOUT 参数。在这种情况下，在非常量变量中传递该内部过程。不允许使用 OUT 参数。出现此问题的原因是需要一个变量来保存内部调用的输出。

内部过程和外部过程之间的关系记录在 `from_sp_call` 的 [SVL\$1STORED\$1PROC\$1CALL](r_SVL_STORED_PROC_CALL.md) 列中。

以下示例演示通过 INOUT 参数将变量传递给嵌套过程调用。

```
CREATE OR REPLACE PROCEDURE inner_proc(INOUT a int, b int, INOUT c int) LANGUAGE plpgsql
AS $$
BEGIN
  a := b * a;
  c := b * c;
END;
$$;

CREATE OR REPLACE PROCEDURE outer_proc(multiplier int) LANGUAGE plpgsql
AS $$
DECLARE
  x int := 3;
  y int := 4;
BEGIN
  DROP TABLE IF EXISTS test_tbl;
  CREATE TEMP TABLE test_tbl(a int, b varchar(256));
  CALL inner_proc(x, multiplier, y);
  insert into test_tbl values (x, y::varchar);
END;
$$;

CALL outer_proc(5);

SELECT * from test_tbl;
 a  | b
----+----
 15 | 20
(1 row)
```

### 驱动程序支持
<a name="r_CALL_procedure-driver-support"></a>

我们建议您将 Java 数据库连接 (JDBC) 和开放式数据库连接 (ODBC) 驱动程序升级到支持 Amazon Redshift 存储过程的最新版本。

如果客户端工具使用通过 CALL 语句传递给服务器的驱动程序 API 操作，则您可以使用现有驱动程序。输出参数（如果有）将作为包含一行的结果集返回。

最新版本的 Amazon Redshift JDBC 和 ODBC 驱动程序对存储过程发现提供元数据支持。这些最新版本对于自定义 Java 应用程序还支持 `CallableStatement`。有关驱动程序的更多信息，请参阅《Amazon Redshift 管理指南》**中的[使用 SQL 客户端工具连接到 Amazon Redshift 集群](https://docs.aws.amazon.com/redshift/latest/mgmt/connecting-to-cluster.html)。

以下示例说明如何对存储过程调用使用 JDBC 驱动程序的不同 API 操作。

```
void statement_example(Connection conn) throws SQLException {
  statement.execute("CALL sp_statement_example(1)");
}

void prepared_statement_example(Connection conn) throws SQLException {
  String sql = "CALL sp_prepared_statement_example(42, 84)";
  PreparedStatement pstmt = conn.prepareStatement(sql);
  pstmt.execute();
}

void callable_statement_example(Connection conn) throws SQLException {
  CallableStatement cstmt = conn.prepareCall("CALL sp_create_out_in(?,?)");
  cstmt.registerOutParameter(1, java.sql.Types.INTEGER);
  cstmt.setInt(2, 42);
  cstmt.executeQuery();
  Integer out_value = cstmt.getInt(1);
}
```

## 示例
<a name="r_CALL_procedure-examples"></a>

以下示例调用过程名称 `test_spl`。

```
call test_sp1(3,'book');
INFO:  Table "tmp_tbl" does not exist and will be skipped
INFO:  min_val = 3, f2 = book
```

以下示例调用过程名称 `test_spl2`。

```
call test_sp2(2,'2019');

         f2          | column2
---------------------+---------
 2019+2019+2019+2019 | 2
(1 row)
```

# CANCEL
<a name="r_CANCEL"></a>

取消当前正在运行的数据库查询。

CANCEL 命令需要正在运行的查询的进程 ID 或会话 ID，并显示一条确认消息来验证查询已取消。

## 所需的权限
<a name="r_CANCEL-privileges"></a>

以下是 CANCEL 所需的权限：
+ 取消自己的查询的超级用户
+ 取消用户的查询的超级用户
+ 取消用户的查询并且具有 CANCEL 权限的用户
+ 取消自己的查询的用户

## 语法
<a name="r_CANCEL-synopsis"></a>

```
CANCEL process_id [ 'message' ]
```

## 参数
<a name="r_CANCEL-parameters"></a>

 *process\$1id*   
要取消在 Amazon Redshift 集群中运行的查询，请使用 [STV\$1RECENTS](r_STV_RECENTS.md) 中与要取消的查询对应的 `pid`（进程 ID）。  
要取消在 Amazon Redshift Serverless 工作组中运行的查询，请使用 [SYS\$1QUERY\$1HISTORY](SYS_QUERY_HISTORY.md) 中与要取消的查询对应的 `session_id`。

'*消息*'  
一条可选的确认消息，该消息在查询取消操作完成时显示。如果您不指定消息，Amazon Redshift 将显示默认的确认消息。您必须将消息放在单引号内。

## 使用说明
<a name="r_CANCEL-usage-notes"></a>

您不能通过指定*查询 ID* 来取消查询；您必须指定查询的*进程 ID*（PID）或*会话 ID*。您只能取消当前由您的用户运行的查询。超级用户可以取消所有查询。

如果多个会话中的查询在同一个表上保留锁定，则可以使用 [PG\$1TERMINATE\$1BACKEND](PG_TERMINATE_BACKEND.md) 函数终止其中一个会话。进行此操作会强制使已终止会话中的任意当前正在运行的查询释放所有死锁并回滚事务。查询 [STV\$1LOCKS](r_STV_LOCKS.md) 系统表可查看当前保留的锁定。

在特定的内部事件之后，Amazon Redshift 可能会重新启动一个活动会话并分配新的 PID。如果 PID 已发生更改，您可能会收到以下错误消息。

```
Session <PID> does not exist. The session PID might have changed. Check the stl_restarted_sessions system table for details.
```

要查找新的 PID，请查询 [STL\$1RESTARTED\$1SESSIONS](r_STL_RESTARTED_SESSIONS.md) 系统表并针对 `oldpid` 列进行筛选。

```
select oldpid, newpid from stl_restarted_sessions where oldpid = 1234;
```

## 示例
<a name="r_CANCEL-examples"></a>

要取消 Amazon Redshift 集群中当前正在运行的查询，请先检索要取消的查询的进程 ID。要确定所有当前正在运行的查询的处理 ID，请键入以下命令：

```
select pid, starttime, duration,
trim(user_name) as user,
trim (query) as querytxt
from stv_recents
where status = 'Running';

pid |         starttime          | duration |   user   |    querytxt
-----+----------------------------+----------+----------+-----------------
802 | 2008-10-14 09:19:03.550885 |      132 | dwuser | select
venuename from venue where venuestate='FL', where venuecity not in
('Miami' , 'Orlando');
834 | 2008-10-14 08:33:49.473585 |  1250414 | dwuser | select *
from listing;
964 | 2008-10-14 08:30:43.290527 |   326179 | dwuser | select
sellerid from sales where qtysold in (8, 10);
```

检查查询文本，确定哪个进程 ID (PID) 对应于您要取消的查询。

键入以下命令以使用 PID 802 来取消该查询：

```
cancel 802;
```

运行查询的会话会显示如下消息：

```
ERROR:  Query (168) cancelled on user's request
```

其中 `168` 是查询 ID (而不是用于取消查询的进程 ID)。

或者，您可以指定显示一条自定义消息，而不是默认消息。要指定自定义消息，请使用单引号将消息包含在 CANCEL 命令的结尾：

```
cancel 802 'Long-running query';
```

运行查询的会话会显示如下消息：

```
ERROR:  Long-running query
```

# CLOSE
<a name="close"></a>

（可选）关闭与已打开游标关联的所有空闲资源。[COMMIT](r_COMMIT.md)、[END](r_END.md) 和 [ROLLBACK](r_ROLLBACK.md) 会自动关闭游标，因此不必使用 CLOSE 命令显式关闭游标。

有关更多信息，请参阅[DECLARE](declare.md)、[FETCH](fetch.md)。

## 语法
<a name="close-synopsis"></a>

```
CLOSE cursor
```

## 参数
<a name="close-parameters"></a>

*cursor*   
要关闭的游标的名称。

## CLOSE 示例
<a name="close-example"></a>

以下命令关闭游标并执行提交，这将结束事务：

```
close movie_cursor;
commit;
```

# COMMENT
<a name="r_COMMENT"></a>

创建或更改有关数据库对象的注释。

## 语法
<a name="r_COMMENT-synopsis"></a>

```
COMMENT ON
{
TABLE object_name |
COLUMN object_name.column_name |
CONSTRAINT constraint_name ON table_name |
DATABASE object_name |
VIEW object_name
}
IS 'text' | NULL
```

## 参数
<a name="r_COMMENT-parameters"></a>

 *object\$1name*   
要添加注释的数据库对象的名称。您可以将注释添加到以下对象：  
+ TABLE
+ COLUMN（还接受 *column\$1name*）。
+ CONSTRAINT（还接受 *constraint\$1name* 和 *table\$1name*）。
+ DATABASE
+ VIEW
+ SCHEMA

IS '*text*' \$1 NULL  
要为指定对象添加或替换的注释文本。*文本*字符串的数据类型是 TEXT。将注释放在单引号内。将值设置为 NULL 可删除注释文本。

 *column\$1name*   
要添加注释的列的名称。COLUMN 的参数。跟随在 `object_name` 中指定的表后面。

 *constraint\$1name*   
要添加注释的约束的名称。CONSTRAINT 的参数。

 *table\$1name*   
包含约束的表的名称。CONSTRAINT 的参数。

## 使用说明
<a name="r_COMMENT-usage-notes"></a>

要添加或更新注释，您必须是超级用户或数据库对象的所有者。

数据库的注释只能应用于当前数据库。如果您尝试对不同的数据库添加注释，则会显示警告消息。对不存在的数据库添加注释时，会显示同一警告。

不支持对外部表、外部列和后期绑定视图的列进行评论。

## 示例
<a name="r_COMMENT-example"></a>

以下示例将注释添加到 SALES 表中。

```
COMMENT ON TABLE sales IS 'This table stores tickets sales data';
```

以下示例在 SALES 表中显示该注释。

```
select obj_description('public.sales'::regclass);

obj_description
-------------------------------------
This table stores tickets sales data
```

以下示例从 SALES 表中删除注释。

```
COMMENT ON TABLE sales IS NULL;
```

以下示例将注释添加到 SALES 表的 EVENTID 列中。

```
COMMENT ON COLUMN sales.eventid IS 'Foreign-key reference to the EVENT table.';
```

以下示例在 SALES 表的 EVENTID 列（列号 5）中显示注释。

```
select col_description( 'public.sales'::regclass, 5::integer );

col_description
-----------------------------------------
Foreign-key reference to the EVENT table.
```

以下示例将描述性注释添加到 EVENT 表。

```
comment on table event is 'Contains listings of individual events.';
```

要查看注释，请查询 PG\$1DESCRIPTION 系统目录。以下示例返回 EVENT 表的描述。

```
select * from pg_catalog.pg_description
where objoid =
(select oid from pg_class where relname = 'event'
and relnamespace =
(select oid from pg_catalog.pg_namespace where nspname = 'public') );

objoid | classoid | objsubid | description
-------+----------+----------+----------------------------------------
116658 |     1259 |        0 | Contains listings of individual events.
```

# COMMIT
<a name="r_COMMIT"></a>

将当前事务提交到数据库。此命令使事务中的数据库更新永久生效。

## 语法
<a name="r_COMMIT-synopsis"></a>

```
COMMIT [ WORK | TRANSACTION ]
```

## 参数
<a name="r_COMMIT-parameters"></a>

WORK  
可选关键字。存储过程中不支持此关键字。

TRANSACTION  
可选关键字。WORK 和 TRANSACTION 是同义词。两者在存储过程中均不受支持。

有关在存储过程中使用 COMMIT 的信息，请参阅[管理事务](stored-procedure-transaction-management.md)。

## 示例
<a name="r_COMMIT-examples"></a>

下面的每个示例都将当前事务提交到数据库：

```
commit;
```

```
commit work;
```

```
commit transaction;
```

# COPY
<a name="r_COPY"></a>


|  | 
| --- |
| 从 2025 年 4 月 30 日起，COPY 和 UNLOAD 命令的客户端加密将不再向新客户开放。如果您在 2025 年 4 月 30 日之前的 12 个月内将客户端加密与 COPY 和 UNLOAD 命令结合使用，则在 2026 年 4 月 30 日之前，可以继续将客户端加密与 COPY 和 UNLOAD 命令结合使用。2026 年 4 月 30 日之后，您无法使用客户端加密进行 COPY 和 UNLOAD。我们建议您尽快切换到使用客户端加密进行 COPY 和 UNLOAD。如果您已经在使用客户端加密进行 COPY 和 UNLOAD，则没有任何变化，您可以在不更改查询的情况下继续使用它。有关 COPY 和 UNLOAD 的加密的更多信息，请参阅下面的 ENCRYPTED 参数。 | 

将数据从数据文件或 Amazon DynamoDB 表加载到表中。这些文件可以位于 Amazon Simple Storage Service (Amazon S3) 桶、Amazon EMR 集群或可使用 Secure Shell (SSH) 连接访问的远程主机中。

**注意**  
Amazon Redshift Spectrum 外部表为只读。您无法对外部表进行 COPY。

COPY 命令会将输入数据作为额外的行附加到表中。

来自任何源的单个输入行的最大大小为 4 MB。

**Topics**
+ [所需的权限](#r_COPY-permissions)
+ [COPY 语法](#r_COPY-syntax)
+ [必需参数](#r_COPY-syntax-required-parameters)
+ [可选参数](#r_COPY-syntax-overview-optional-parameters)
+ [COPY 命令的使用说明和其它资源](#r_COPY-using-the-copy-command)
+ [COPY 命令示例](#r_COPY-using-the-copy-command-examples)
+ [COPY JOB](r_COPY-JOB.md)
+ [使用 TEMPLATE 进行 COPY](r_COPY-WITH-TEMPLATE.md)
+ [COPY 参数参考](r_COPY-parameters.md)
+ [使用说明](r_COPY_usage_notes.md)
+ [COPY 示例](r_COPY_command_examples.md)

## 所需的权限
<a name="r_COPY-permissions"></a>

要使用 COPY 命令，您必须对 Amazon Redshift 表拥有 [INSERT](r_GRANT.md#grant-insert) 权限。

## COPY 语法
<a name="r_COPY-syntax"></a>

```
COPY table-name 
[ column-list ]
FROM data_source
authorization
[ [ FORMAT ] [ AS ] data_format ] 
[ parameter [ argument ] [, ... ] ]
```

只需 3 个参数即可执行 COPY 操作：表名称、数据来源和对数据的访问的授权。

Amazon Redshift 扩展了 COPY 命令的功能，使您可以从多个数据来源加载多种数据格式的数据、控制对加载数据的访问权限、管理数据转换和管理加载操作。

以下各节介绍所需的 COPY 命令参数，并按功能对可选参数进行分组。其中还会介绍每个参数并说明各个选项如何配合使用。您可以通过使用按字母顺序排列的参数列表直接转到相应的参数说明。

## 必需参数
<a name="r_COPY-syntax-required-parameters"></a>

COPY 命令需要三个元素：
+ [Table Name](#r_COPY-syntax-overview-table-name)
+ [Data Source](#r_COPY-syntax-overview-data-source)
+ [Authorization](#r_COPY-syntax-overview-credentials)

最简单的 COPY 命令使用以下格式。

```
COPY table-name 
FROM data-source
authorization;
```

以下示例创建一个名为 CATDEMO 的表，然后从 Amazon S3 中名为 `category_pipe.txt` 的数据文件加载包含样本数据的表。

```
create table catdemo(catid smallint, catgroup varchar(10), catname varchar(10), catdesc varchar(50));
```

在以下示例中，COPY 命令的数据来源是一个数据文件，名为 `category_pipe.txt`，位于名为 `redshift-downloads` 的 Amazon S3 桶的 `tickit` 文件夹中。COPY 命令有权通过 AWS Identity and Access Management (IAM) 角色访问 Amazon S3 桶。如果您的集群具有有权访问附加的 Amazon S3 的现有 IAM 角色，您可以在以下 COPY 命令中替换您的角色的 Amazon 资源名称 (ARN) 并执行该角色。

```
copy catdemo
from 's3://redshift-downloads/tickit/category_pipe.txt'
iam_role 'arn:aws:iam::<aws-account-id>:role/<role-name>'
region 'us-east-1';
```

有关如何使用 COPY 命令加载示例数据的完整说明，包括从其他 AWS 区域加载数据的说明，请参阅《Amazon Redshift 入门指南》中的[从 Amazon S3 中加载示例数据](https://docs.aws.amazon.com/redshift/latest/gsg/rs-gsg-create-sample-db.html)。

*table-name*  <a name="r_COPY-syntax-overview-table-name"></a>
COPY 命令的目标表的名称。该表必须已存在于数据库中。该表可以是临时的或永久的。COPY 命令会将新输入数据追加到该表中的任何现有行。

FROM *data-source*  <a name="r_COPY-syntax-overview-data-source"></a>
要加载到目标表中的源数据的位置。可使用某些数据来源指定清单文件。  
最常用的数据存储库是 Amazon S3 桶。您还可以从位于 Amazon EMR 集群中、位于 Amazon EC2 实例中或位于您的集群可使用 SSH 连接访问的远程主机中的数据文件加载，或者也可以直接从 DynamoDB 表加载。  
+ [从 Amazon S3 执行 COPY 操作](copy-parameters-data-source-s3.md)
+ [从 Amazon EMR 执行 COPY 操作](copy-parameters-data-source-emr.md) 
+ [从远程主机中执行 COPY 操作 (SSH)](copy-parameters-data-source-ssh.md)
+ [从 Amazon DynamoDB 执行 COPY 操作](copy-parameters-data-source-dynamodb.md)

授权  <a name="r_COPY-syntax-overview-credentials"></a>
一个子句，指示您的集群用于访问其他 AWS 资源的身份验证和授权的方法。COPY 命令需要授权才能访问其他 AWS 资源（包括 Amazon S3、Amazon EMR、Amazon DynamoDB 和 Amazon EC2）中的数据。您可通过引用附加到您的集群的 IAM 角色或通过为 IAM 用户提供访问密钥 ID 和秘密访问密钥来提供该授权。  
+ [授权参数](copy-parameters-authorization.md) 
+ [基于角色的访问控制](copy-usage_notes-access-permissions.md#copy-usage_notes-access-role-based) 
+ [基于密钥的访问控制](copy-usage_notes-access-permissions.md#copy-usage_notes-access-key-based) 

## 可选参数
<a name="r_COPY-syntax-overview-optional-parameters"></a>

您可以选择性地指定 COPY 命令如何将字段数据映射到目标表中的列，定义源数据属性以便让 COPY 命令正确读取和分析源数据，以及管理 COPY 命令在加载过程中执行的操作。
+ [列映射选项](copy-parameters-column-mapping.md)
+ [数据格式参数](#r_COPY-syntax-overview-data-format)
+ [数据转换参数](#r_COPY-syntax-overview-data-conversion)
+ [数据加载操作](#r_COPY-syntax-overview-data-load)

### 列映射
<a name="r_COPY-syntax-overview-column-mapping"></a>

默认情况下，COPY 会按字段在数据文件中出现的相同顺序将字段值插入到目标表的列中。如果默认列顺序不起作用，则可以指定一个列列表或使用 JSONPath 表达式将源数据字段映射到目标列。
+ [Column List](copy-parameters-column-mapping.md#copy-column-list)
+ [JSONPaths File](copy-parameters-column-mapping.md#copy-column-mapping-jsonpaths)

### 数据格式参数
<a name="r_COPY-syntax-overview-data-format"></a>

您可以从固定宽度、字符分隔、逗号分隔值 (CSV)、JSON 格式的文本文件加载数据，也可从 Avro 文件加载数据。

默认情况下，COPY 命令要求源数据位于字符分隔的 UTF-8 文本文件中。默认分隔符是竖线字符 (\$1)。如果源数据采用的是其他格式，请使用以下参数指定数据格式。
+ [FORMAT](copy-parameters-data-format.md#copy-format)
+ [CSV](copy-parameters-data-format.md#copy-csv)
+ [DELIMITER](copy-parameters-data-format.md#copy-delimiter) 
+ [FIXEDWIDTH](copy-parameters-data-format.md#copy-fixedwidth) 
+ [SHAPEFILE](copy-parameters-data-format.md#copy-shapefile) 
+ [AVRO](copy-parameters-data-format.md#copy-avro) 
+ [JSON format for COPY](copy-parameters-data-format.md#copy-json) 
+ [ENCRYPTED](copy-parameters-data-source-s3.md#copy-encrypted) 
+ [BZIP2](copy-parameters-file-compression.md#copy-bzip2) 
+ [GZIP](copy-parameters-file-compression.md#copy-gzip) 
+ [LZOP](copy-parameters-file-compression.md#copy-lzop) 
+ [PARQUET](copy-parameters-data-format.md#copy-parquet) 
+ [ORC](copy-parameters-data-format.md#copy-orc) 
+ [ZSTD](copy-parameters-file-compression.md#copy-zstd) 

### 数据转换参数
<a name="r_COPY-syntax-overview-data-conversion"></a>

在加载表时，COPY 会尝试将源数据中的字符串隐式转换为目标列的数据类型。如果您需要指定不同于默认行为的转换，或者默认转换会产生错误，则可以通过指定以下参数来管理数据转换。
+ [ACCEPTANYDATE](copy-parameters-data-conversion.md#copy-acceptanydate) 
+ [ACCEPTINVCHARS](copy-parameters-data-conversion.md#copy-acceptinvchars) 
+ [BLANKSASNULL](copy-parameters-data-conversion.md#copy-blanksasnull) 
+ [DATEFORMAT](copy-parameters-data-conversion.md#copy-dateformat) 
+ [EMPTYASNULL](copy-parameters-data-conversion.md#copy-emptyasnull) 
+ [ENCODING](copy-parameters-data-conversion.md#copy-encoding) 
+ [ESCAPE](copy-parameters-data-conversion.md#copy-escape) 
+ [EXPLICIT_IDS](copy-parameters-data-conversion.md#copy-explicit-ids) 
+ [FILLRECORD](copy-parameters-data-conversion.md#copy-fillrecord) 
+ [IGNOREBLANKLINES](copy-parameters-data-conversion.md#copy-ignoreblanklines) 
+ [IGNOREHEADER](copy-parameters-data-conversion.md#copy-ignoreheader) 
+ [NULL AS](copy-parameters-data-conversion.md#copy-null-as) 
+ [REMOVEQUOTES](copy-parameters-data-conversion.md#copy-removequotes) 
+ [ROUNDEC](copy-parameters-data-conversion.md#copy-roundec) 
+ [TIMEFORMAT](copy-parameters-data-conversion.md#copy-timeformat) 
+ [TRIMBLANKS](copy-parameters-data-conversion.md#copy-trimblanks) 
+ [TRUNCATECOLUMNS](copy-parameters-data-conversion.md#copy-truncatecolumns) 

### 数据加载操作
<a name="r_COPY-syntax-overview-data-load"></a>

通过指定以下参数来管理加载操作的默认行为，以进行故障排除或缩短加载时间。
+ [COMPROWS](copy-parameters-data-load.md#copy-comprows) 
+ [COMPUPDATE](copy-parameters-data-load.md#copy-compupdate) 
+ [IGNOREALLERRORS](copy-parameters-data-load.md#copy-ignoreallerrors) 
+ [MAXERROR](copy-parameters-data-load.md#copy-maxerror) 
+ [NOLOAD](copy-parameters-data-load.md#copy-noload) 
+ [STATUPDATE](copy-parameters-data-load.md#copy-statupdate) 

## COPY 命令的使用说明和其它资源
<a name="r_COPY-using-the-copy-command"></a>

有关如何使用 COPY 命令的更多信息，请参阅以下主题：
+ [使用说明](r_COPY_usage_notes.md)
+ [教程：从 Amazon S3 加载数据](tutorial-loading-data.md)
+ [Amazon Redshift 加载数据的最佳实践](c_loading-data-best-practices.md)
+ [使用 COPY 命令加载表](t_Loading_tables_with_the_COPY_command.md)
  + [从 Amazon S3 加载数据](t_Loading-data-from-S3.md)
  + [从 Amazon EMR 中加载数据](loading-data-from-emr.md)
  + [从远程主机中加载数据](loading-data-from-remote-hosts.md) 
  + [从 Amazon DynamoDB 表中加载数据](t_Loading-data-from-dynamodb.md)
+ [解决数据加载问题](t_Troubleshooting_load_errors.md)

## COPY 命令示例
<a name="r_COPY-using-the-copy-command-examples"></a>

有关展示如何使用不同来源、不同格式和不同的 COPY 选项执行 COPY 操作的更多示例，请参阅[COPY 示例](r_COPY_command_examples.md)。

# COPY JOB
<a name="r_COPY-JOB"></a>

有关使用此命令的信息，请参阅[创建 S3 事件集成以自动从 Amazon S3 存储桶复制文件](loading-data-copy-job.md)。

管理将数据加载到表中的 COPY 命令。COPY JOB 命令是 COPY 命令的扩展，可自动从 Amazon S3 桶加载数据。当您创建 COPY 作业时，Amazon Redshift 会检测何时在指定路径中创建新的 Amazon S3 文件，然后自动加载这些文件，无需您的干预。加载数据时使用的参数与原始 COPY 命令中使用的参数相同。Amazon Redshift 保持跟踪加载的文件（基于文件名），以确认它们只加载一次。

**注意**  
有关 COPY 命令的信息，包括用法、参数和权限，请参阅 [COPY](r_COPY.md)。

## 所需的权限
<a name="r_COPY-JOB-privileges"></a>

要使用 COPY JOB 命令，除了使用 COPY 所需的所有权限外，您还必须拥有以下权限之一：
+ Superuser
+  以下所有权限：
  +  与在要 COPY 到的数据库中执行 COPY JOBS 操作相关的 CREATE、ALTER 或 DROP 限定范围权限。
  +  对要 COPY 到的架构的 USAGE 权限，或者对要 COPY 到的数据库中架构的 USAGE 限定范围权限。
  +  对要 COPY 到的表的 INSERT 权限，或者对要 COPY 到的架构或数据库中的表的 INSERT 限定范围权限。

使用 COPY 命令指定的 IAM 角色必须具有访问待加载数据的权限。有关更多信息，请参阅 [COPY、UNLOAD 和 CREATE LIBRARY 的 IAM 权限](copy-usage_notes-access-permissions.md#copy-usage_notes-iam-permissions)。

## 语法
<a name="r_COPY-JOB-syntax"></a>

创建复制作业。COPY 命令的参数与复制作业一起保存。

您不能在事务块的范围内运行 COPY JOB CREATE。

```
COPY copy-command JOB CREATE job-name
[AUTO ON | OFF]
```

更改复制作业的配置。

```
COPY JOB ALTER job-name
[AUTO ON | OFF]
```

运行复制作业。使用存储的 COPY 命令参数。

```
COPY JOB RUN job-name
```

列出所有复制作业。

```
COPY JOB LIST
```

显示复制作业的详细信息。

```
COPY JOB SHOW job-name
```

删除复制作业。

您不能在事务区的范围内运行 COPY JOB DROP。

```
COPY JOB DROP job-name
```

## 参数
<a name="r_COPY-JOB-parameters"></a>

*copy-command*  
COPY 命令将数据从 Amazon S3 加载到 Amazon Redshift。该子句包含用于定义 Amazon S3 桶、目标表、IAM 角色的 COPY 参数，以及加载数据时使用的其他参数。支持用于 Amazon S3 数据加载的所有 COPY 命令参数，但以下参数除外：  
+ COPY JOB 不会摄取 COPY 命令指向的文件夹中已有的文件。只有在 COPY JOB 创建时间戳之后创建的文件才会被摄取。
+ 不能使用 MAXERROR 或 IGNOREALLERRORS 选项指定 COPY 命令。
+ 不能指定清单文件。COPY JOB 需要指定的 Amazon S3 位置来监控新创建的文件。
+ 不能使用访问密钥和私有密钥等授权类型指定 COPY 命令。仅支持使用 `IAM_ROLE` 参数进行授权的 COPY 命令。有关更多信息，请参阅 [授权参数](copy-parameters-authorization.md)。
+ COPY JOB 不支持与集群关联的默认 IAM 角色。必须在 COPY 命令中指定 `IAM_ROLE`。
有关更多信息，请参阅 [从 Amazon S3 执行 COPY 操作](copy-parameters-data-source-s3.md)。

*job-name*  
用于引用 COPY JOB 的作业的名称。*job-name* 不能包含连字符（‐）。

 [AUTO ON \$1 OFF]   
该子句指示 Amazon S3 数据是否自动加载到 Amazon Redshift 表中。  
+ 选项为 `ON` 时，Amazon Redshift 会监控源 Amazon S3 路径中新创建的文件，如果找到新创建的文件，则使用作业定义中的 COPY 参数运行 COPY 命令。这是默认值。
+ 选项为 `OFF` 时，Amazon Redshift 不会自动运行 COPY JOB。

## 使用说明
<a name="r_COPY-JOB-usage-notes"></a>

COPY 命令的选项要等到运行时才会验证。例如，在 COPY JOB 启动时，无效的 `IAM_ROLE` 或 Amazon S3 数据来源会导致出现运行时错误。

如果暂停集群，则不运行 COPY JOB。

要查询已加载的 COPY 命令文件和加载错误，请参见 [STL\$1LOAD\$1COMMITS](r_STL_LOAD_COMMITS.md)、[STL\$1LOAD\$1ERRORS](r_STL_LOAD_ERRORS.md) 和 [STL\$1LOADERROR\$1DETAIL](r_STL_LOADERROR_DETAIL.md)。有关更多信息，请参阅 [验证是否正确加载了数据](verifying-that-data-loaded-correctly.md)。

零 ETL 数据库不支持 COPY JOBS，因为它们在只读模式下运行。

## 示例
<a name="r_COPY-JOB-examples"></a>

以下示例显示创建 COPY JOB 以从 Amazon S3 桶加载数据。

```
COPY public.target_table
FROM 's3://amzn-s3-demo-bucket/staging-folder'
IAM_ROLE 'arn:aws:iam::123456789012:role/MyLoadRoleName' 
JOB CREATE my_copy_job_name
AUTO ON;
```

# 使用 TEMPLATE 进行 COPY
<a name="r_COPY-WITH-TEMPLATE"></a>

您可以将 Redshift 模板与 COPY 命令结合使用，以简化命令语法并确保数据加载操作间的一致性。无需重复指定相同的格式化参数，而是在模板中定义它们一次，然后在 COPY 命令中引用模板。使用模板时，COPY 命令会将模板中的参数与在命令中直接指定的任何参数相结合。如果同一个参数同时出现在模板和命令中，则命令参数优先。有关更多信息，请参阅 [CREATE TEMPLATE](r_CREATE_TEMPLATE.md)。

可以使用以下各项创建 COPY 命令的模板：
+ [数据格式参数](copy-parameters-data-format.md)
+ [文件压缩参数](copy-parameters-file-compression.md)
+ [数据转换参数](copy-parameters-data-conversion.md)
+ [数据加载操作](copy-parameters-data-load.md)

有关支持的参数的完整列表，请参阅 [COPY](r_COPY.md) 命令。

## 所需的权限
<a name="r_COPY-WITH-TEMPLATE-privileges"></a>

要在 COPY 命令中使用模板，您必须拥有：
+ 执行 COPY 命令所需的所有权限（请参阅[所需的权限](r_COPY.md#r_COPY-permissions)）
+ 以下模板权限之一：
  + 超级用户权限
  + 对模板拥有 USAGE 权限，并对包含模板的架构拥有 USAGE 权限

## 语法
<a name="r_COPY-WITH-TEMPLATE-syntax"></a>

```
COPY target_table FROM 's3://...'
authorization
[ option, ...]
USING TEMPLATE [database_name.][schema_name.]template_name;
```

## 参数
<a name="r_COPY-WITH-TEMPLATE-parameters"></a>

 *database\$1name*   
（可选）模板所在数据库的名称。如果未指定，则使用当前数据库。

 *schema\$1name*   
（可选）模板所在架构的名称。如果未指定，则在当前搜索路径中搜索模板。

 *template\$1name*   
COPY 中要使用的模板的名称。

## 使用说明
<a name="r_COPY-WITH_TEMPLATE-usage-notes"></a>
+ 仍必须在 COPY 命令中指定特定于命令的参数（源、目标、授权）。
+ 模板不能包含 COPY 命令的清单文件规范。

## 示例
<a name="r_COPY-WITH-TEMPLATE-examples"></a>

以下示例演示如何创建模板并在 COPY 命令中使用它：

```
CREATE TEMPLATE public.test_template FOR COPY AS
CSV DELIMITER '|' IGNOREHEADER 1 MAXERROR 100;

COPY public.target_table
FROM 's3://amzn-s3-demo-bucket/staging-folder'
IAM_ROLE 'arn:aws:iam::123456789012:role/MyLoadRoleName'
USING TEMPLATE public.test_template;
```

当某个参数同时存在于模板和命令中时，命令参数优先。在此示例中，如果模板 `public.test_template` 包含 `DELIMITER '|'`，但 COPY 命令指定 `DELIMITER ','`，则将使用命令中的逗号分隔符 (`,`)，而不是模板中的管道分隔符 (`|`)。

```
COPY public.target_table
FROM 's3://amzn-s3-demo-bucket/staging-folder'
IAM_ROLE 'arn:aws:iam::123456789012:role/MyLoadRoleName'
DELIMITER ','
USING TEMPLATE public.test_template;
```

# COPY 参数参考
<a name="r_COPY-parameters"></a>

COPY 有许多可以在多种情况下使用的参数。但是，并不是所有参数在每种情况下都受支持。例如，要从 ORC 或 PARQUET 文件加载，支持的参数数量有限。有关更多信息，请参阅 [从列式数据格式中执行 COPY 操作](copy-usage_notes-copy-from-columnar.md)。

**Topics**
+ [数据来源](copy-parameters-data-source.md)
+ [授权参数](copy-parameters-authorization.md)
+ [列映射选项](copy-parameters-column-mapping.md)
+ [数据格式参数](copy-parameters-data-format.md)
+ [文件压缩参数](copy-parameters-file-compression.md)
+ [数据转换参数](copy-parameters-data-conversion.md)
+ [数据加载操作](copy-parameters-data-load.md)
+ [按字母顺序排列的参数列表](r_COPY-alphabetical-parm-list.md)

# 数据来源
<a name="copy-parameters-data-source"></a>

您可以从位于 Amazon S3 桶中、位于 Amazon EMR 集群中或位于您的集群可使用 SSH 连接访问的远程主机上的文本文件加载数据。您也可以直接从 DynamoDB 表加载数据。

来自任何源的单个输入行的最大大小为 4 MB。

要将表中的数据导出到 Amazon S3 中的一组文件，请使用 [UNLOAD](r_UNLOAD.md) 命令。

**Topics**
+ [从 Amazon S3 执行 COPY 操作](copy-parameters-data-source-s3.md)
+ [从 Amazon EMR 执行 COPY 操作](copy-parameters-data-source-emr.md)
+ [从远程主机中执行 COPY 操作 (SSH)](copy-parameters-data-source-ssh.md)
+ [从 Amazon DynamoDB 执行 COPY 操作](copy-parameters-data-source-dynamodb.md)

# 从 Amazon S3 执行 COPY 操作
<a name="copy-parameters-data-source-s3"></a>

要从位于一个或多个 S3 桶中的文件加载数据，请使用 FROM 子句指示 COPY 在 Amazon S3 中查找文件的方式。您可以提供数据文件的对象路径作为 FROM 子句的一部分，也可以提供包含了 Amazon S3 对象路径列表的清单文件的位置。从 Amazon S3 执行 COPY 操作将使用 HTTPS 连接。确保将 S3 IP 范围添加到您的允许列表中。要了解有关所需 S3 IP 范围的更多信息，请参阅[网络隔离](https://docs.aws.amazon.com//redshift/latest/mgmt/security-network-isolation.html#network-isolation)。

**重要**  
如果包含数据文件的 Amazon S3 桶未驻留在您的集群所在的 AWS 区域内，则必须使用 [REGION](#copy-region) 参数指定数据所在的区域。

**Topics**
+ [语法](#copy-parameters-data-source-s3-syntax)
+ [示例](#copy-parameters-data-source-s3-examples)
+ [可选参数](#copy-parameters-data-source-s3-optional-parms)
+ [不支持的参数](#copy-parameters-data-source-s3-unsupported-parms)

## 语法
<a name="copy-parameters-data-source-s3-syntax"></a>

```
FROM { 's3://objectpath' | 's3://manifest_file' }
authorization
| MANIFEST
| ENCRYPTED
| REGION [AS] 'aws-region'
| optional-parameters
```

## 示例
<a name="copy-parameters-data-source-s3-examples"></a>

以下示例使用对象路径从 Amazon S3 加载数据。

```
copy customer
from 's3://amzn-s3-demo-bucket/customer' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

以下示例使用清单文件从 Amazon S3 加载数据。

```
copy customer
from 's3://amzn-s3-demo-bucket/cust.manifest' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
manifest;
```

### 参数
<a name="copy-parameters-data-source-s3-parameters"></a>

FROM  <a name="copy-parameters-from"></a>
要加载的数据的源。有关 Amazon S3 文件编码的更多信息，请参阅[数据转换参数](copy-parameters-data-conversion.md)。

's3://*copy\$1from\$1s3\$1objectpath*'  <a name="copy-s3-objectpath"></a>
指定包含数据的 Amazon S3 对象的路径，例如 `'s3://amzn-s3-demo-bucket/custdata.txt'`。*s3://copy\$1from\$1s3\$1objectpath* 参数可引用单个文件或者具有相同键前缀的一组对象或文件夹。例如，名称 `custdata.txt` 是引用很多物理文件（`custdata.txt`、`custdata.txt.1`，等等）的键前缀。`custdata.txt.2``custdata.txt.bak`键前缀还可以引用很多文件夹。例如，`'s3://amzn-s3-demo-bucket/custfolder'` 引用文件夹 `custfolder`、`custfolder_1`，等等。`custfolder_2`如果键前缀引用多个文件夹，则加载这些文件夹中的所有文件。如果键前缀与一个文件以及一个文件夹匹配，如 `custfolder.log`，COPY 还将尝试加载该文件。如果键前缀可能导致 COPY 尝试加载不需要的文件，请使用清单文件。有关更多信息，请参阅以下内容：[copy_from_s3_manifest_file](#copy-manifest-file)。  
如果包含数据文件的 S3 桶未驻留在您的集群所在的 AWS 区域内，则必须使用 [REGION](#copy-region) 参数指定数据所在的区域。
有关更多信息，请参阅 [从 Amazon S3 加载数据](t_Loading-data-from-S3.md)。

's3://*copy\$1from\$1s3\$1manifest\$1file*'  <a name="copy-manifest-file"></a>
为列出了要加载的数据文件的清单文件指定 Amazon S3 对象键。*'s3://*copy\$1from\$1s3\$1manifest\$1file'** 参数必须显式引用单个文件，例如`'s3://amzn-s3-demo-bucket/manifest.txt'`。它不能引用键前缀。  
清单是 JSON 格式的文本文件，其中列出了要从 Amazon S3 加载的每个文件的 URL。URL 包含文件的桶名称和完整对象路径。在清单中指定的文件可以位于不同的桶中，但所有桶都必须位于 Amazon Redshift 集群所在的同一 AWS 区域。如果某个文件被列出两次，那么该文件也会被加载两次。以下示例显示了加载三个文件的清单的 JSON。  

```
{
  "entries": [
    {"url":"s3://amzn-s3-demo-bucket1/custdata.1","mandatory":true},
    {"url":"s3://amzn-s3-demo-bucket1/custdata.2","mandatory":true},
    {"url":"s3://amzn-s3-demo-bucket2/custdata.1","mandatory":false}
  ]
}
```
需要双引号字符，并且必须是简单引号 (0x22)，而不能是斜引号或“智能”引号。清单中的每个条目都可以选择性地包含 `mandatory` 标记。如果 `mandatory` 设置为 `true`，则当 COPY 未找到该条目对应的文件时，该命令将会终止；否则，该命令将继续。`mandatory` 的默认值为 `false`。  
在从采用 ORC 或 Parquet 格式的数据文件中加载时，需要 `meta` 字段，如以下示例所示。  

```
{  
   "entries":[  
      {  
         "url":"s3://amzn-s3-demo-bucket1/orc/2013-10-04-custdata",
         "mandatory":true,
         "meta":{  
            "content_length":99
         }
      },
      {  
         "url":"s3://amzn-s3-demo-bucket2/orc/2013-10-05-custdata",
         "mandatory":true,
         "meta":{  
            "content_length":99
         }
      }
   ]
}
```
不能对清单文件进行加密或压缩，即使指定了 ENCRYPTED、GZIP、LZOP、BZIP2 或 ZSTD 选项。如果未找到指定的清单文件或清单文件的格式不正确，COPY 命令将返回错误。  
如果使用了清单文件，则必须使用 COPY 命令指定 MANIFEST 参数。如果未指定 MANIFEST 参数，COPY 命令将假定使用 FROM 指定的文件是数据文件。  
有关更多信息，请参阅 [从 Amazon S3 加载数据](t_Loading-data-from-S3.md)。

*授权*  
COPY 命令需要授权才能访问其他 AWS 资源（包括 Amazon S3 、Amazon EMR、Amazon DynamoDB 和 Amazon EC2）中的数据。您可通过引用附加到您的集群的 AWS Identity and Access Management (IAM) 角色（基于角色的访问控制）或者通过为用户提供访问凭证（基于密钥的访问控制）来提供授权。为了提高安全性和灵活性，我们建议使用基于 IAM 角色的访问控制。有关更多信息，请参阅 [授权参数](copy-parameters-authorization.md)。

MANIFEST  <a name="copy-manifest"></a>
指定使用一个清单来标识要从 Amazon S3 加载的数据文件。如果使用了 MANIFEST 参数，则 COPY 将从 *'s3://copy\$1from\$1s3\$1manifest\$1file'* 引用的清单中列出的文件加载数据。如果未找到清单文件或清单文件的格式不正确，COPY 将失败。有关更多信息，请参阅 [使用清单指定数据文件](loading-data-files-using-manifest.md)。

ENCRYPTED  <a name="copy-encrypted"></a>
一个子句，指定 Amazon S3 上输入文件的加密方法为：利用客户管理的密钥进行客户端加密。有关更多信息，请参阅 [从 Amazon S3 中加载加密的数据文件](c_loading-encrypted-files.md)。如果输入文件的加密方法为 Amazon S3 服务器端加密（SSE-KMS 或 SSE-S3），请不要指定 ENCRYPTED。COPY 会自动读取服务器端加密的文件。  
如果您要指定 ENCRYPTED 参数，还必须指定 [MASTER_SYMMETRIC_KEY](#copy-master-symmetric-key) 参数，或在 **master\$1symmetric\$1key** 字符串中包括 [使用 CREDENTIALS 参数](copy-parameters-authorization.md#copy-credentials) 值。  
如果加密文件采用了压缩格式，请添加 GZIP、LZOP、BZIP2 或 ZSTD 参数。  
即使指定了 ENCRYPTED 选项，也不得加密清单文件和 JSONPaths 文件。

MASTER\$1SYMMETRIC\$1KEY '*root\$1key*'  <a name="copy-master-symmetric-key"></a>
用于在 Amazon S3 上加密数据文件的根对称密钥。如果指定了 MASTER\$1SYMMETRIC\$1KEY，还须指定 [ENCRYPTED](#copy-encrypted) 参数。MASTER\$1SYMMETRIC\$1KEY 不能与 CREDENTIALS 参数配合使用。有关更多信息，请参阅 [从 Amazon S3 中加载加密的数据文件](c_loading-encrypted-files.md)。  
如果加密文件采用了压缩格式，请添加 GZIP、LZOP、BZIP2 或 ZSTD 参数。

REGION [AS] '*aws-region*'  <a name="copy-region"></a>
指定源数据所在的 AWS 区域。当包含该数据的 AWS 资源与 Amazon Redshift 集群不在同一区域时，从 Amazon S3 桶或 DynamoDB 表执行 COPY 的操作需要 REGION。  
*aws\$1region* 的值必须与 [Amazon Redshift 区域和端点](https://docs.aws.amazon.com/general/latest/gr/rande.html#redshift_region)表中所列的区域匹配。  
如果指定了 REGION 参数，则所有资源（包括清单文件或多个 Amazon S3 桶）都必须位于指定区域内。  
对于包含数据的 Amazon S3 桶或 DynamoDB 表，跨区域传输数据将会产生额外费用。有关定价的更多信息，请参阅 [Amazon S3 定价](https://aws.amazon.com/s3/pricing/)页面上的**将数据从 Amazon S3 移出到另一个 AWS 区域**和 [Amazon DynamoDB 定价](https://aws.amazon.com/dynamodb/pricing/)页面上的**移出数据**。
预设情况下，COPY 假定数据位于 Amazon Redshift 集群所在的相同区域。

## 可选参数
<a name="copy-parameters-data-source-s3-optional-parms"></a>

对于从 Amazon S3 执行 COPY 的操作，还可以指定以下参数：
+ [列映射选项](copy-parameters-column-mapping.md)
+ [数据格式参数](copy-parameters-data-format.md#copy-data-format-parameters)
+ [数据转换参数](copy-parameters-data-conversion.md)
+ [数据加载操作](copy-parameters-data-load.md)

## 不支持的参数
<a name="copy-parameters-data-source-s3-unsupported-parms"></a>

对于从 Amazon S3 执行 COPY 的操作，不能使用以下参数：
+ SSH
+ READRATIO

# 从 Amazon EMR 执行 COPY 操作
<a name="copy-parameters-data-source-emr"></a>

您可以使用 COPY 命令从一个具有如下配置的 Amazon EMR 集群并行加载数据：将文本文件以固定宽度文件、字符分隔文件、CSV 文件、JSON 格式文件或 Avro 文件的形式写入到集群的 Hadoop Distributed File System (HDFS)。

**Topics**
+ [语法](#copy-parameters-data-source-emr-syntax)
+ [示例](#copy-parameters-data-source-emr-example)
+ [参数](#copy-parameters-data-source-emr-parameters)
+ [支持的参数](#copy-parameters-data-source-emr-optional-parms)
+ [不支持的参数](#copy-parameters-data-source-emr-unsupported-parms)

## 语法
<a name="copy-parameters-data-source-emr-syntax"></a>

```
FROM 'emr://emr_cluster_id/hdfs_filepath'  
authorization
[ optional_parameters ]
```

## 示例
<a name="copy-parameters-data-source-emr-example"></a>

以下示例从一个 Amazon EMR 集群加载数据。

```
copy sales
from 'emr://j-SAMPLE2B500FC/myoutput/part-*' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

## 参数
<a name="copy-parameters-data-source-emr-parameters"></a>

FROM  
要加载的数据的源。

 'emr://*emr\$1cluster\$1id*/*hdfs\$1file\$1path*'  <a name="copy-emr"></a>
Amazon EMR 集群的唯一标识符和引用 COPY 命令的数据文件的 HDFS 文件路径。HDFS 数据文件名不能包含通配符星号 (\$1) 和问号 (?)。  
在 COPY 操作完成前，Amazon EMR 集群必须持续运行。如果在 COPY 操作完成前更改或删除了任何 HDFS 数据文件，则您可能得到意外的结果，或者 COPY 操作可能会失败。
您可以使用通配符星号 (\$1) 和问号 (?) 作为 *hdfs\$1file\$1path* 参数的一部分来指定要加载的多个文件。例如，`'emr://j-SAMPLE2B500FC/myoutput/part*'` 标识文件 `part-0000`、`part-0001`，等等。如果文件路径不包含通配符，则将其视为文字字符串。如果您仅指定一个文件夹名称，则 COPY 将尝试加载该文件夹中的所有文件。  
如果您使用通配符或仅使用文件夹名称，请确认将不会加载不需要的文件。例如，某些流程可能会将日志文件写入到输出文件夹。
有关更多信息，请参阅 [从 Amazon EMR 中加载数据](loading-data-from-emr.md)。

*授权*  
COPY 命令需要授权才能访问其他 AWS 资源（包括 Amazon S3 、Amazon EMR、Amazon DynamoDB 和 Amazon EC2）中的数据。您可通过引用附加到您的集群的 AWS Identity and Access Management (IAM) 角色（基于角色的访问控制）或者通过为用户提供访问凭证（基于密钥的访问控制）来提供授权。为了提高安全性和灵活性，我们建议使用基于 IAM 角色的访问控制。有关更多信息，请参阅 [授权参数](copy-parameters-authorization.md)。

## 支持的参数
<a name="copy-parameters-data-source-emr-optional-parms"></a>

对于从 Amazon EMR 执行 COPY 的操作，还可以指定以下参数：
+ [列映射选项](copy-parameters-column-mapping.md)
+ [数据格式参数](copy-parameters-data-format.md#copy-data-format-parameters)
+ [数据转换参数](copy-parameters-data-conversion.md)
+ [数据加载操作](copy-parameters-data-load.md)

## 不支持的参数
<a name="copy-parameters-data-source-emr-unsupported-parms"></a>

对于从 Amazon EMR 执行 COPY 的操作，不能使用以下参数：
+ ENCRYPTED
+ MANIFEST
+ REGION
+ READRATIO
+ SSH

# 从远程主机中执行 COPY 操作 (SSH)
<a name="copy-parameters-data-source-ssh"></a>

您可使用 COPY 命令从一台或多台远程主机并行加载数据，例如 Amazon Elastic Compute Cloud (Amazon EC2) 实例或其他计算机。COPY 使用 Secure Shell (SSH) 连接到远程主机并在远程主机上运行命令以生成文本输出。远程主机可以是 EC2 Linux 实例或配置为接受 SSH 连接的另一台 Unix 或 Linux 计算机。Amazon Redshift 可连接到多台主机，并可以打开到每台主机的多个 SSH 连接。Amazon Redshift 会通过每个连接发送一个唯一命令来生成到主机标准输出的文本输出，然后 Amazon Redshift 会像读取文本文件一样读取它。

使用 FROM 子句指定一个清单文件的 Amazon S3 对象键，该清单文件提供 COPY 用于建立 SSH 连接并执行远程命令的信息。

**Topics**
+ [语法](#copy-parameters-data-source-ssh-syntax)
+ [示例](#copy-parameters-data-source-ssh-examples)
+ [参数](#copy-parameters-data-source-ssh-parameters)
+ [可选参数](#copy-parameters-data-source-ssh-optional-parms)
+ [不支持的参数](#copy-parameters-data-source-ssh-unsupported-parms)

**重要**  
 如果包含清单文件的 S3 桶未驻留在您的集群所在的 AWS 区域内，则必须使用 REGION 参数指定该桶所在的区域。

## 语法
<a name="copy-parameters-data-source-ssh-syntax"></a>

```
FROM 's3://'ssh_manifest_file' }
authorization
SSH
| optional-parameters
```

## 示例
<a name="copy-parameters-data-source-ssh-examples"></a>

以下示例使用清单文件从使用 SSH 的远程主机加载数据。

```
copy sales
from 's3://amzn-s3-demo-bucket/ssh_manifest' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
ssh;
```

## 参数
<a name="copy-parameters-data-source-ssh-parameters"></a>

FROM  
要加载的数据的源。

's3://*copy\$1from\$1ssh\$1manifest\$1file*'  <a name="copy-ssh-manifest"></a>
COPY 命令可连接到使用 SSH 的多台主机，并可以与每台主机建立多个 SSH 连接。COPY 通过每个主机连接运行一个命令，然后将来自这些命令的输出并行加载到表中。*s3://copy\$1from\$1ssh\$1manifest\$1file* 参数指定一个清单文件的 Amazon S3 对象键，该清单文件提供 COPY 将用于建立 SSH 连接并执行远程命令的信息。  
*s3://copy\$1from\$1ssh\$1manifest\$1file* 参数必须显式引用单个文件；它不能是键前缀。下面是一个示例：  

```
's3://amzn-s3-demo-bucket/ssh_manifest.txt'
```
清单文件是 Amazon Redshift 用于连接主机的文本文件，采用 JSON 格式。清单文件指定 SSH 主机端点以及将在主机上运行的用于将数据返回到 Amazon Redshift 的命令。另外，您还可以包含主机公有密钥、登录用户名和每个条目的 mandatory 标志。以下示例显示了用于创建两个 SSH 连接的清单文件：  

```
{ 
    "entries": [ 
	    {"endpoint":"<ssh_endpoint_or_IP>", 
           "command": "<remote_command>",
           "mandatory":true, 
           "publickey": "<public_key>", 
           "username": "<host_user_name>"}, 
	    {"endpoint":"<ssh_endpoint_or_IP>", 
           "command": "<remote_command>",
           "mandatory":true, 
           "publickey": "<public_key>", 
           "username": "<host_user_name>"} 
     ] 
}
```
该清单文件为每个 SSH 连接包含一个 `"entries"` 结构。您可以与单台主机建立多个连接或与多台主机建立多个连接。如上所示，字段名称和值均需要使用双引号字符。引号字符必须是简单引号 (0x22)，而不能是倾斜引号或“智能”引号。唯一一个不需要双引号字符的值是 `"mandatory"` 字段的布尔值 `true` 或 `false`。  
以下列表介绍了清单文件中的字段。    
endpoint  <a name="copy-ssh-manifest-endpoint"></a>
主机的 URL 地址或 IP 地址，例如 `"ec2-111-222-333.compute-1.amazonaws.com"` 或 `"198.51.100.0"`。  
命令  <a name="copy-ssh-manifest-command"></a>
命令通过主机运行，用以产生 gzip、lzop、bzip2 或 zstd 格式的文本输出或二进制输出。该命令可以是用户 *"host\$1user\$1name"* 有权运行的任何命令。该命令可以是像打印文件这样简单的命令，也可以查询数据库或启动脚本。输出（文本文件、gzip 二进制文件、lzop 二进制文件或 bzip2 二进制文件）必须采用 Amazon Redshift COPY 命令可摄取的形式。有关更多信息，请参阅 [准备输入数据](t_preparing-input-data.md)。  
publickey  <a name="copy-ssh-manifest-publickey"></a>
（可选）主机的公有密钥。如果提供了公有密钥，Amazon Redshift 将使用它来标识主机。如果未提供公有密钥，Amazon Redshift 将不会尝试主机标识。例如，如果远程主机的公有密钥是 `ssh-rsa AbcCbaxxx…Example root@amazon.com`，请在公有密钥字段中键入以下文本：`"AbcCbaxxx…Example"`  
mandatory  <a name="copy-ssh-manifest-mandatory"></a>
（可选）一个子句，指示在连接尝试失败时 COPY 命令是否应失败。默认为 `false`。如果 Amazon Redshift 未成功建立至少一个连接，COPY 命令将失败。  
username  <a name="copy-ssh-manifest-username"></a>
（可选）将用于登录到主机系统并执行远程命令的用户名。用户登录名必须与用于将 Amazon Redshift 集群的公有密钥添加到主机的授权密钥文件的登录名相同。默认用户名为 `redshift`。
有关创建清单文件的更多信息，请参阅[加载数据的过程](loading-data-from-remote-hosts.md#load-from-host-process)。  
要从远程主机执行 COPY 操作，则必须在 COPY 命令中指定 SSH 参数。如果未指定 SSH 参数，COPY 命令将假定使用 FROM 指定的文件是数据文件，操作将会失败。  
如果使用自动压缩，COPY 命令将执行两个数据读取操作，这意味着它将执行远程命令两次。第一个读取操作用于提供压缩分析的数据样本，第二个读取操作实际加载数据。如果执行远程命令两次可能会导致问题，则应禁用自动压缩。要禁用自动压缩，请在运行 COPY 命令时将 COMPUPDATE 参数设置为 OFF。有关更多信息，请参阅 [使用自动压缩加载表](c_Loading_tables_auto_compress.md)。  
有关从 SSH 执行 COPY 操作的详细过程，请参阅[从远程主机中加载数据](loading-data-from-remote-hosts.md)。

*授权*  
COPY 命令需要授权才能访问其他 AWS 资源（包括 Amazon S3 、Amazon EMR、Amazon DynamoDB 和 Amazon EC2）中的数据。您可通过引用附加到您的集群的 AWS Identity and Access Management (IAM) 角色（基于角色的访问控制）或者通过为用户提供访问凭证（基于密钥的访问控制）来提供授权。为了提高安全性和灵活性，我们建议使用基于 IAM 角色的访问控制。有关更多信息，请参阅 [授权参数](copy-parameters-authorization.md)。

SSH  <a name="copy-ssh"></a>
一个子句，指定要从使用 SSH 协议的远程主机加载数据。如果指定 SSH，则必须使用 [s3://copy_from_ssh_manifest_file](#copy-ssh-manifest) 参数提供清单文件。  
如果您通过 SSH 在远程 VPC 中使用私有 IP 地址从主机进行复制，则 VPC 必须启用增强型 VPC 路由。有关增强型 VPC 路由的更多信息，请参阅 [Amazon Redshift 增强型 VPC 路由](https://docs.aws.amazon.com/redshift/latest/mgmt/enhanced-vpc-routing.html)。

## 可选参数
<a name="copy-parameters-data-source-ssh-optional-parms"></a>

对于从 SSH 执行 COPY 的操作，还可以选择指定以下参数：
+ [列映射选项](copy-parameters-column-mapping.md)
+ [数据格式参数](copy-parameters-data-format.md#copy-data-format-parameters)
+ [数据转换参数](copy-parameters-data-conversion.md)
+ [数据加载操作](copy-parameters-data-load.md)

## 不支持的参数
<a name="copy-parameters-data-source-ssh-unsupported-parms"></a>

对于从 SSH 执行 COPY 的操作，不能使用以下参数：
+ ENCRYPTED
+ MANIFEST
+ READRATIO

# 从 Amazon DynamoDB 执行 COPY 操作
<a name="copy-parameters-data-source-dynamodb"></a>

要从现有 DynamoDB 表加载数据，请使用 FROM 子句指定 DynamoDB 表名称。

**Topics**
+ [语法](#copy-parameters-data-source-dynamodb-syntax)
+ [示例](#copy-parameters-data-source-dynamodb-examples)
+ [可选参数](#copy-parameters-data-source-dynamodb-optional-parms)
+ [不支持的参数](#copy-parameters-data-source-dynamodb-unsupported-parms)

**重要**  
如果 DynamoDB 表未驻留在您的 Amazon Redshift 集群所在的区域内，则必须使用 REGION 参数指定该数据所在的区域。

## 语法
<a name="copy-parameters-data-source-dynamodb-syntax"></a>

```
FROM 'dynamodb://table-name' 
authorization
READRATIO ratio
| REGION [AS] 'aws_region'  
| optional-parameters
```

## 示例
<a name="copy-parameters-data-source-dynamodb-examples"></a>

以下示例从 DynamoDB 表加载数据。

```
copy favoritemovies from 'dynamodb://ProductCatalog'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
readratio 50;
```

### 参数
<a name="copy-parameters-data-source-dynamodb-parameters"></a>

FROM  
要加载的数据的源。

'dynamodb://*table-name*'  <a name="copy-dynamodb"></a>
包含数据的 DynamoDB 表的名称，例如 `'dynamodb://ProductCatalog'`。有关 DynamoDB 属性如何映射到 Amazon Redshift 列的详细信息，请参阅[从 Amazon DynamoDB 表中加载数据](t_Loading-data-from-dynamodb.md)。  
DynamoDB 表名称对于由 AWS 访问凭证标识的 AWS 账户是唯一的。

*授权*  
COPY 命令需要授权才能访问其他 AWS 资源（包括 Amazon S3 、Amazon EMR、DynamoDB 和 Amazon EC2）中的数据。您可通过引用附加到您的集群的 AWS Identity and Access Management (IAM) 角色（基于角色的访问控制）或者通过为用户提供访问凭证（基于密钥的访问控制）来提供授权。为了提高安全性和灵活性，我们建议使用基于 IAM 角色的访问控制。有关更多信息，请参阅 [授权参数](copy-parameters-authorization.md)。

READRATIO [AS] *ratio*  <a name="copy-readratio"></a>
DynamoDB 表的预配置吞吐量中要用于数据加载的部分所占的百分比。从 DynamoDB 执行 COPY 的操作需要 READRATIO。它不能在从 Amazon S3 执行 COPY 的操作中使用。我们强烈建议您将此比率设置为一个低于平均的未使用预配置吞吐量的值。有效值为整数 1–200。  
将 READRATIO 设置为 100 或更大值将使 Amazon Redshift 消耗 DynamoDB 表的全部预配置吞吐量，从而严重降低 COPY 会话期间对同一个表进行的并行读取操作的性能。写入流量不受影响。允许使用大于 100 的值来应对 Amazon Redshift 无法满足表的预配置吞吐量的罕见情况。如果将 DynamoDB 中的数据持续加载到 Amazon Redshift，请考虑按时间序列组织 DynamoDB 表以将实时流量与 COPY 操作分离。

## 可选参数
<a name="copy-parameters-data-source-dynamodb-optional-parms"></a>

对于从 Amazon DynamoDB 执行 COPY 的操作，还可以指定以下参数：
+ [列映射选项](copy-parameters-column-mapping.md)
+ 支持以下数据转换参数：
  + [ACCEPTANYDATE](copy-parameters-data-conversion.md#copy-acceptanydate) 
  + [BLANKSASNULL](copy-parameters-data-conversion.md#copy-blanksasnull) 
  + [DATEFORMAT](copy-parameters-data-conversion.md#copy-dateformat) 
  + [EMPTYASNULL](copy-parameters-data-conversion.md#copy-emptyasnull) 
  + [ROUNDEC](copy-parameters-data-conversion.md#copy-roundec) 
  + [TIMEFORMAT](copy-parameters-data-conversion.md#copy-timeformat) 
  + [TRIMBLANKS](copy-parameters-data-conversion.md#copy-trimblanks) 
  + [TRUNCATECOLUMNS](copy-parameters-data-conversion.md#copy-truncatecolumns) 
+ [数据加载操作](copy-parameters-data-load.md)

## 不支持的参数
<a name="copy-parameters-data-source-dynamodb-unsupported-parms"></a>

对于从 DynamoDB 执行 COPY 的操作，不能使用以下参数：
+ 所有数据格式参数
+ ESCAPE
+ FILLRECORD
+ IGNOREBLANKLINES
+ IGNOREHEADER
+ NULL
+ REMOVEQUOTES
+ ACCEPTINVCHARS
+ MANIFEST
+ ENCRYPTED

# 授权参数
<a name="copy-parameters-authorization"></a>

COPY 命令需要授权才能访问其他 AWS 资源（包括 Amazon S3、Amazon EMR、Amazon DynamoDB 和 Amazon EC2）中的数据。您通过引用附加到集群的 [AWS Identity and Access Management (IAM) 角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html)来提供授权（*基于角色的访问控制*）。您可以在 Amazon S3 上加密您的加载数据。

以下主题将提供有关身份验证选项的更多详细信息和示例：
+ [COPY、UNLOAD 和 CREATE LIBRARY 的 IAM 权限](copy-usage_notes-access-permissions.md#copy-usage_notes-iam-permissions)
+ [基于角色的访问控制](copy-usage_notes-access-permissions.md#copy-usage_notes-access-role-based)
+ [基于密钥的访问控制](copy-usage_notes-access-permissions.md#copy-usage_notes-access-key-based)

使用以下参数之一为 COPY 命令提供授权：
+ [使用 IAM\$1ROLE 参数](#copy-iam-role) parameter
+ [使用 ACCESS\$1KEY\$1ID 和 SECRET\$1ACCESS\$1KEY 参数](#copy-access-key-id) 参数
+ [使用 CREDENTIALS 参数](#copy-credentials) 子句

## 使用 IAM\$1ROLE 参数
<a name="copy-iam-role"></a>

### IAM\$1ROLE
<a name="copy-iam-role-iam"></a>

使用默认关键字让 Amazon Redshift 使用设置为默认值并在 COPY 命令运行时与集群关联的 IAM 角色。

使用 IAM 角色的 Amazon 资源名称 (ARN)，您的集群使用该角色进行身份验证和授权。如果您指定 IAM\$1ROLE，则无法使用 ACCESS\$1KEY\$1ID 和 SECRET\$1ACCESS\$1KEY、SESSION\$1TOKEN 或 CREDENTIALS。

以下显示 IAM\$1ROLE 参数的语法。

```
IAM_ROLE { default | 'arn:aws:iam::<AWS 账户-id>:role/<role-name>' }
```

有关更多信息，请参阅 [基于角色的访问控制](copy-usage_notes-access-permissions.md#copy-usage_notes-access-role-based)。

## 使用 ACCESS\$1KEY\$1ID 和 SECRET\$1ACCESS\$1KEY 参数
<a name="copy-access-key-id"></a>

### ACCESS\$1KEY\$1ID、SECRET\$1ACCESS\$1KEY
<a name="copy-access-key-id-access"></a>

不建议您使用此授权方法。

**注意**  
我们强烈建议通过指定 IAM\$1ROLE 参数使用基于角色的身份验证，而不是提供纯文本形式的访问凭证。有关更多信息，请参阅 [基于角色的访问控制](copy-usage_notes-access-permissions.md#copy-usage_notes-access-role-based)。

### SESSION\$1TOKEN
<a name="copy-token"></a>

与临时访问凭证配合使用的会话令牌。如果指定 SESSION\$1TOKEN，还必须使用 ACCESS\$1KEY\$1ID 和 SECRET\$1ACCESS\$1KEY 提供临时访问密钥凭证。如果指定 SESSION\$1TOKEN，则不能使用 IAM\$1ROLE 或 CREDENTIALS。有关更多信息，请参阅《IAM 用户指南》中的[临时安全凭证](copy-usage_notes-access-permissions.md#r_copy-temporary-security-credentials)。

**注意**  
我们强烈建议使用基于角色的身份验证，而不是创建临时安全凭证。如果您授权使用 IAM 角色，Amazon Redshift 会自动为每个会话创建临时用户凭证。有关更多信息，请参阅 [基于角色的访问控制](copy-usage_notes-access-permissions.md#copy-usage_notes-access-role-based)。

以下显示 SESSION\$1TOKEN 参数与 ACCESS\$1KEY\$1ID 和 SECRET\$1ACCESS\$1KEY 参数配合使用时的语法。

```
ACCESS_KEY_ID '<access-key-id>'
SECRET_ACCESS_KEY '<secret-access-key>'
SESSION_TOKEN '<temporary-token>';
```

如果指定 SESSION\$1TOKEN，则不能使用 CREDENTIALS 或 IAM\$1ROLE。

## 使用 CREDENTIALS 参数
<a name="copy-credentials"></a>

### CREDENTIALS
<a name="copy-credentials-cred"></a>

一个子句，指示您的集群在访问包含数据文件或清单文件的其他 AWS 资源时将使用的方法。CREDENTIALS 参数不能与 IAM\$1ROLE 或 ACCESS\$1KEY\$1ID 和 SECRET\$1ACCESS\$1KEY 配合使用。

下面显示 CREDENTIALS 参数的语法。

```
[WITH] CREDENTIALS [AS] 'credentials-args'
```

**注意**  
要获得更高的灵活性，我们建议使用 [IAM\$1ROLE](#copy-iam-role-iam) 参数，而不是 CREDENTIALS 参数。

（可选）如果使用了 [ENCRYPTED](copy-parameters-data-source-s3.md#copy-encrypted) 参数，*credentials-args* 字符串还将提供加密密钥。

*credentials-args* 字符串区分大小写且不得包含空格。

关键字 WITH 和 AS 是可选的，将被忽略。

您可指定 [role-based access control](copy-usage_notes-access-permissions.md#copy-usage_notes-access-role-based.phrase) 或 [key-based access control](copy-usage_notes-access-permissions.md#copy-usage_notes-access-key-based.phrase)。在任一情况下，IAM 角色或用户都必须具有访问指定 AWS 资源所需的权限。有关更多信息，请参阅 [COPY、UNLOAD 和 CREATE LIBRARY 的 IAM 权限](copy-usage_notes-access-permissions.md#copy-usage_notes-iam-permissions)。

**注意**  
为了保护您的 AWS 凭证和敏感数据，我们强烈建议使用基于角色的访问控制。

要指定基于角色的访问控制，请按以下格式提供 *credentials-args* 字符串。

```
'aws_iam_role=arn:aws:iam::<aws-account-id>:role/<role-name>'
```

要使用临时令牌凭证，您必须提供临时访问密钥 ID、临时秘密访问密钥和临时令牌。*credentials-args* 字符串采用以下格式。

```
CREDENTIALS
'aws_access_key_id=<temporary-access-key-id>;aws_secret_access_key=<temporary-secret-access-key>;token=<temporary-token>'
```

使用基于角色的访问控制及临时凭证的 COPY 命令类似于以下示例语句：

```
COPY customer FROM 's3://amzn-s3-demo-bucket/mydata' 
CREDENTIALS
'aws_access_key_id=<temporary-access-key-id>;aws_secret_access_key=<temporary-secret-access-key-id>;token=<temporary-token>'
```

 有关更多信息，请参阅 [临时安全凭证](copy-usage_notes-access-permissions.md#r_copy-temporary-security-credentials)。

如果使用了 [ENCRYPTED](copy-parameters-data-source-s3.md#copy-encrypted) 参数，*credentials-args* 字符串将采用以下格式，其中 *<root-key>* 是用于对文件进行加密的根密钥的值。

```
CREDENTIALS
'<credentials-args>;master_symmetric_key=<root-key>'
```

使用基于角色的访问控制及加密密钥的 COPY 命令类似于以下示例语句：

```
COPY customer FROM 's3://amzn-s3-demo-bucket/mydata' 
CREDENTIALS 
'aws_iam_role=arn:aws:iam::<account-id>:role/<role-name>;master_symmetric_key=<root-key>'
```

# 列映射选项
<a name="copy-parameters-column-mapping"></a>

默认情况下，COPY 会按字段在数据文件中出现的相同顺序将值插入到目标表的列中。如果默认列顺序不起作用，则可以指定一个列列表或使用 JSONPath 表达式将源数据字段映射到目标列。
+ [Column List](#copy-column-list)
+ [JSONPaths File](#copy-column-mapping-jsonpaths)

## 列列表
<a name="copy-column-list"></a>

您可以指定列名称的逗号分隔列表以将源数据字段加载到特定目标列中。这些列在 COPY 语句中可以采用任何顺序，但是，当从平面文件加载时（如在 Amazon S3 桶中），它们的顺序必须与源数据的顺序一致。

从 Amazon DynamoDB 表加载时，顺序并不重要。COPY 命令将从 DynamoDB 表中检索到的项中的属性名称与 Amazon Redshift 表中的列名进行匹配。有关更多信息，请参阅[从 Amazon DynamoDB 表中加载数据](t_Loading-data-from-dynamodb.md)

 列列表的格式如下所示。

```
COPY tablename (column1 [,column2, ...]) 
```

如果列列表省略了目标表中的列，则 COPY 将加载目标列的 [DEFAULT](r_CREATE_TABLE_NEW.md#create-table-default) 表达式。

如果目标列没有默认值，则 COPY 将尝试加载 NULL。

如果 COPY 尝试将 NULL 分配到一个定义为 NOT NULL 的列，COPY 命令将失败。

如果 [IDENTITY](r_CREATE_TABLE_NEW.md#identity-clause) 列包含在列列表中，则还必须指定 [EXPLICIT_IDS](copy-parameters-data-conversion.md#copy-explicit-ids)；如果省略了 IDENTITY 列，则无法指定 EXPLICIT\$1IDS。如果未指定任何列列表，则该命令将如同指定了一个完整、有序的列列表一样来执行，如果也未指定 EXPLICIT\$1IDS，则会省略 IDENTITY 列。

如果某个列使用 GENERATED BY DEFAULT AS IDENTITY 进行定义，则可以复制该列。使用您提供的值生成或更新值。EXPLICIT\$1IDS 选项不是必需项。COPY 不会更新身份高级别水印。有关更多信息，请参阅 [GENERATED BY DEFAULT AS IDENTITY](r_CREATE_TABLE_NEW.md#identity-generated-bydefault-clause)。

## JSONPaths 文件
<a name="copy-column-mapping-jsonpaths"></a>

当从 JSON 或 Avro 格式的数据文件加载时，COPY 会将 JSON 或 Avro 源数据中的数据元素自动映射到目标表中的列。它的执行方式是通过将 Avro schema 中的字段名称与目标表或列列表中的列名称相匹配。

在某些情况下，您的列名称与字段名称不匹配，或者您需要映射到数据层次结构中的更深层次。在这些情况下，您可以使用 JSONPaths 文件将 JSON 或 Avro 数据元素显式映射到列。

有关更多信息，请参阅 [JSONPaths 文件](copy-parameters-data-format.md#copy-json-jsonpaths)。

# 数据格式参数
<a name="copy-parameters-data-format"></a>

默认情况下，COPY 命令要求源数据是字符分隔的 UTF-8 文本。默认分隔符是竖线字符 (\$1)。如果源数据采用的是其他格式，请使用以下参数指定数据格式：
+ [FORMAT](#copy-format)
+ [CSV](#copy-csv)
+ [DELIMITER](#copy-delimiter) 
+ [FIXEDWIDTH](#copy-fixedwidth) 
+ [SHAPEFILE](#copy-shapefile) 
+ [AVRO](#copy-avro) 
+ [JSON format for COPY](#copy-json) 
+ [PARQUET](#copy-parquet) 
+ [ORC](#copy-orc) 

除标准数据格式以外，COPY 支持 Amazon S3 中有关 COPY 的以下列式数据格式：
+ [ORC](#copy-orc) 
+ [PARQUET](#copy-parquet) 

支持列式中的 COPY，其中带有特定限制。有关更多信息，请参阅 [从列式数据格式中执行 COPY 操作](copy-usage_notes-copy-from-columnar.md)。<a name="copy-data-format-parameters"></a>数据格式参数

FORMAT [AS]  <a name="copy-format"></a>
（可选）标识数据格式关键字。FORMAT 参数如下所述。

CSV [ QUOTE [AS] *'quote\$1character'* ]  <a name="copy-csv"></a>
支持在输入数据中使用 CSV 格式。要自动对分隔符、换行符和回车符进行转义，可用 QUOTE 参数指定的字符将字段括起来。默认引号字符是双引号 ( " )。当在字段中使用了引号字符时，应使用另一个引号字符对其进行转义。例如，如果引号字符为双引号，那么要插入字符串 `A "quoted" word`，输入文件应包含字符串 `"A ""quoted"" word"`。当使用了 CSV 参数时，默认分隔符为逗号 (,)。您可使用 DELIMITER 参数指定一个不同的分隔符。  
当某个字段用引号括起来时，分隔符和引号字符之间的空格将被忽略。如果分隔符为空格字符（如制表符），则分隔符不会被视为空格。  
CSV 不能与 FIXEDWIDTH、REMOVEQUOTES 或 ESCAPE 一起使用。    
QUOTE [AS] *'quote\$1character'*  <a name="copy-csv-quote"></a>
可选。指定在使用 CSV 参数时要用作引号字符的字符。默认值为双引号 (")。如果您使用 QUOTE 参数定义双引号以外的引号字符，则不需要对字段中的双引号进行转义。QUOTE 参数只能与 CSV 参数一起使用。AS 关键字是可选的。

DELIMITER [AS] ['*delimiter\$1char*']   <a name="copy-delimiter"></a>
指定用于在输入文件中分隔各个字段的字符，如竖线字符 (`|`)、逗号 (`,`)、制表符 (`\t`) 或多个字符，如 `|~|`。支持不可打印的字符。字符也可以用八进制表示为其 UTF-8 代码单元。对于八进制，使用格式“\$1ddd”，其中“d”是八进制数字（0–7）。默认分隔符是竖线字符 (`|`)，除非使用了 CSV 参数，在这种情况下，默认分隔符是逗号 (`,`)。AS 关键字是可选的。DELIMITER 不能与 FIXEDWIDTH 一起使用。

FIXEDWIDTH '*fixedwidth\$1spec*'  <a name="copy-fixedwidth"></a>
从一个文件中加载数据，该文件中的每个列是宽度固定的列，而不是由分隔符分隔的列。*fixedwidth\$1spec* 是用于指定用户定义的列标签和列宽度的字符串。列标签可以是文本字符串或整数，具体取决于用户的选择。列标签与列名称没有关联。标签/宽度对的顺序必须与表列的顺序完全一致。FIXEDWIDTH 不能与 CSV 或 DELIMITER 一起使用。在 Amazon Redshift 中，CHAR 和 VARCHAR 列的长度以字节表示，因此在准备要加载的文件时，请确保您指定的列宽度可容纳多字节字符的二进制长度。有关更多信息，请参阅 [字符类型](r_Character_types.md)。  
*fixedwidth\$1spec* 的格式如下所示：  

```
'colLabel1:colWidth1,colLabel:colWidth2, ...'
```

SHAPEFILE [ SIMPLIFY [AUTO] [*'tolerance'*] ]  <a name="copy-shapefile"></a>
支持在输入数据中使用 SHAPEFILE 格式。预设情况下，shapefile 的第一列是 `GEOMETRY` 或 `IDENTITY` 列。所有后续列都遵循 shapefile 中指定的顺序。  
您不能将 SHAPEFILE 与 FIXEDWIDTH、REMOVEQUOTES 或 ESCAPE 一起使用。  
要将 `GEOGRAPHY` 对象与 `COPY FROM SHAPEFILE` 一起使用，请首先提取到 `GEOMETRY` 列，然后将对象强制转换为 `GEOGRAPHY` 对象。    
SIMPLIFY [*tolerance*]  <a name="copy-shapefile-simplify"></a>
（可选）使用 Ramer-Douglas-Peucker 算法和给定的容差简化摄入过程中的所有几何体。  
SIMPLIFY AUTO [*tolerance*]  <a name="copy-shapefile-simplify"></a>
（可选）仅简化大于最大几何大小的几何体。这种简化使用 Ramer-Douglas-Peucker 算法和自动计算的容差（如果不超过指定容差）。此算法计算在指定容差范围内存储对象的大小。*公差*值是可选的。
有关加载 shapefile 的示例，请参阅[将 shapefile 加载到 Amazon Redshift](r_COPY_command_examples.md#copy-example-spatial-copy-shapefile)。

AVRO [AS] '*avro\$1option*'  <a name="copy-avro"></a>
指定源数据采用 Avro 格式。  
从以下服务和协议执行 COPY 的操作支持 Avro 格式：  
+ Amazon S3 
+ Amazon EMR 
+ 远程主机 (SSH) 
从 DynamoDB 执行 COPY 的操作不支持 Avro。  
Avro 是一个数据序列化协议。Avro 源文件包含一个定义数据结构的 schema。Avro schema 类型必须为 `record`。COPY 接受使用默认的非压缩编解码器及 `deflate` 和 `snappy` 压缩编解码器创建的 Avro 文件。有关 Avro 的更多信息，请转到 [Apache Avro](https://avro.apache.org/)。  
*avro\$1option* 的有效值如下：  
+ `'auto'`
+ `'auto ignorecase'`
+ `'s3://jsonpaths_file'` 
默认为 `'auto'`。  
COPY 会将 Avro 源数据中的数据元素自动映射到目标表中的列。它的执行方式是通过将 Avro schema 中的字段名称与目标表中的列名称相匹配。`'auto'` 的匹配区分大小写，`'auto ignorecase'` 的匹配不区分大小写。  
Amazon Redshift 表中的列名称始终小写，因此，当您使用 `'auto'` 选项时，匹配的字段名称也必须为小写。如果字段名称不是全部小写，则可以使用 `'auto ignorecase'` 选项。使用默认的 `'auto'` 参数时，COPY 仅识别结构中的第一层字段，或*外部字段*。  
要将列名称显式映射到 Avro 字段名称，您可以使用 [JSONPaths 文件](#copy-json-jsonpaths)。  
默认情况下，COPY 会尝试将目标表中的所有列与 Avro 字段名称匹配。要加载列的子集，您可以选择性地指定包含列的列表。如果列列表中省略了目标表中的列，则 COPY 将加载目标列的 [DEFAULT](r_CREATE_TABLE_NEW.md#create-table-default) 表达式。如果目标列没有默认值，则 COPY 将尝试加载 NULL。如果某个列包含在列列表中，并且 COPY 在 Avro 数据中找不到匹配的字段，则 COPY 会尝试将 NULL 加载到该列中。  
如果 COPY 尝试将 NULL 分配到一个定义为 NOT NULL 的列，COPY 命令将失败。  
<a name="copy-avro-schema"></a>**Avro Schema**  
Avro 源数据文件包含一个定义数据结构的 Schema。COPY 将读取作为 Avro 源数据文件的一部分的 schema 以将数据元素映射到目标表列。以下示例显示了一个 Avro schema。  

```
{
    "name": "person",
    "type": "record",
    "fields": [
        {"name": "id", "type": "int"},
        {"name": "guid", "type": "string"},
        {"name": "name", "type": "string"},
        {"name": "address", "type": "string"}]
}
```
Avro schema 是使用 JSON 格式定义的。顶级 JSON 对象包含三个名称-值对，这三个名称（即*键*）分别为 `"name"`、`"type"` 和 `"fields"`。  
`"fields"` 键与定义数据结构中每个字段的名称和数据类型的对象数组配对。默认情况下，COPY 会自动将字段名称与列名称匹配。列名称始终为小写形式，因此匹配的字段名称也必须为小写形式，除非您指定了 `‘auto ignorecase’` 选项。与列名称不匹配的任何字段名称都将被忽略。顺序无关紧要。在上述示例中，COPY 将映射到列名称 `id`、`guid`、`name` 和 `address`。  
由于存在默认的 `'auto'` 参数，COPY 只会将第一层对象映射到列。若要映射到 schema 中的更深层次，或者如果字段名称与列名称不匹配，请使用 JSONPaths 文件定义映射。有关更多信息，请参阅 [JSONPaths 文件](#copy-json-jsonpaths)。  
如果与键关联的值是一个复杂的 Avro 数据类型（如字节、数组、记录、映射或链接），COPY 会将该值作为一个字符串加载。这里的字符串是数据的 JSON 表示形式。COPY 会将 Avro 枚举数据类型作为字符串加载，其中的内容是类型的名称。有关示例，请参阅 [从 JSON 格式数据执行的 COPY 操作](copy-usage_notes-copy-from-json.md)。  
Avro 文件标头（包括 schema 和文件元数据）的最大大小为 1 MB。    
单个 Avro 数据块的最大大小为 4 MB。这与最大行大小不同。如果超过了单个 Avro 数据块的最大大小，则即使生成的行大小未达到 4 MB 的行大小限制，COPY 命令也会失败。  
在计算行大小时，Amazon Redshift 在内部对竖线字符 ( \$1 ) 计为两个字符。如果您的输入数据中包含大量竖线字符，则即使数据块小于 4 MB，行大小也可能超过 4 MB。

JSON [AS] '*json\$1option*'  <a name="copy-json"></a>
源数据采用 JSON 格式。  
从以下服务和协议执行 COPY 的操作支持 JSON 格式：  
+ Amazon S3
+ 从 Amazon EMR 执行 COPY 操作
+ 从 SSH 执行 COPY 的操作
从 DynamoDB 执行 COPY 的操作不支持 JSON。  
*json\$1option* 的有效值如下：  
+ `'auto'`
+ `'auto ignorecase'`
+ `'s3://jsonpaths_file'` 
+ `'noshred'` 
默认为 `'auto'`。在加载 JSON 文档时，Amazon Redshift 不会将 JSON 结构的属性分解为多个列。  
默认情况下，COPY 会尝试将目标表中的所有列与 JSON 字段名称键匹配。要加载列的子集，您可以选择性地指定包含列的列表。如果 JSON 字段名称键包含大写字符，则您可以使用 `'auto ignorecase'` 选项或 [JSONPaths 文件](#copy-json-jsonpaths) 将列名称显式地映射到 JSON 字段名称键。  
如果列列表省略了目标表中的列，则 COPY 将加载目标列的 [DEFAULT](r_CREATE_TABLE_NEW.md#create-table-default) 表达式。如果目标列没有默认值，则 COPY 将尝试加载 NULL。如果某个列包含在列列表中，并且 COPY 在 JSON 数据中找不到匹配的字段，则 COPY 会尝试将 NULL 加载到该列。  
如果 COPY 尝试将 NULL 分配到一个定义为 NOT NULL 的列，COPY 命令将失败。  
COPY 会将 JSON 源数据中的数据元素映射到目标表中的列。它的操作方式是通过将源名称-值对中的*对象键*（即名称）与目标表中的列名称匹配。  
请参阅以下有关每个 *json\$1option* 值的详细信息：    
'auto'  <a name="copy-json-auto"></a>
使用此选项时，匹配区分大小写。Amazon Redshift 表中的列名称始终小写，因此，当您使用 `'auto'` 选项时，匹配的 JSON 字段名称也必须为小写。  
“auto ignorecase”  <a name="copy-json-auto-ignorecase"></a>
使用此选项时，匹配不区分大小写。Amazon Redshift 表中的列名称始终为小写，因此，当您使用 `'auto ignorecase'` 选项时，相应的 JSON 字段名称可以是小写、大写或大小写混合。  
's3://*jsonpaths\$1file*'  <a name="copy-json-pathfile"></a>
通过此选项，COPY 使用命名的 JSONPaths 文件将 JSON 源数据中的数据元素映射到目标表中的列。*`s3://jsonpaths_file`* 参数必须是显式引用单个文件的 Amazon S3 对象键。示例是 `'s3://amzn-s3-demo-bucket/jsonpaths.txt`'。参数不能为键前缀。有关使用 JSONPaths 文件的更多信息，请参阅 [JSONPaths 文件](#copy-json-jsonpaths)。  
在某些情况下，由 `jsonpaths_file` 指定的文件的前缀与由 `copy_from_s3_objectpath` 为数据文件指定的路径的前缀相同。如果是这样，COPY 会将 JSONPaths 文件作为数据文件读取并返回错误。例如，假设您的数据文件使用对象路径 `s3://amzn-s3-demo-bucket/my_data.json`，并且您的 JSONPaths 文件是 `s3://amzn-s3-demo-bucket/my_data.jsonpaths`。在这种情况下，COPY 会尝试加载 `my_data.jsonpaths` 作为数据文件。  
“noshred”  <a name="copy-json-noshred"></a>
使用此选项，Amazon Redshift 不会在加载 JSON 文档时将 JSON 结构的属性分解为多个列。

## JSON 数据文件
<a name="copy-json-data-file"></a>

JSON 数据文件包含一组对象或数组。COPY 会将每个 JSON 对象或数组加载到目标表中的一行中。与某个行对应的每个对象或数组都必须是独立的根级结构；即，它不能是另一个 JSON 结构的成员。

JSON *对象* 以大括号 (\$1 \$1) 开头和结尾，并包含名称-值对的无序集合。每个成对的名称和值由冒号分隔，而每个名称/值对由逗号分隔。预设情况下，名称-值对中的*对象键*（即名称）必须与表中的对应列的名称匹配。Amazon Redshift 表中的列名称始终小写，因此，匹配的 JSON 字段名称键也必须为小写。如果您的列名称与 JSON 键不匹配，请使用 [JSONPaths 文件](#copy-json-jsonpaths) 将列显式映射到键。

JSON 对象中的顺序不重要。与列名称不匹配的任何名称都将被忽略。下面显示了一个简单 JSON 对象的结构。

```
{
  "column1": "value1",
  "column2": value2,
  "notacolumn" : "ignore this value"
}
```

JSON *数组* 以中括号 ([]) 开头和结尾，并包含由逗号分隔的值的有序集合。如果您的数据文件使用了数组，则必须指定 JSONPaths 文件以将值与列匹配。下面显示了一个简单 JSON 数组的结构。

```
["value1", value2]
```

JSON 必须格式正确。例如，对象或数组不能用逗号或除空格以外的任何其他字符分隔。字符串必须括在双引号字符中。引号字符必须是简单引号 (0x22)，而不能是倾斜引号或“智能”引号。

单个 JSON 对象或数组（包括大括号或中括号）的最大大小为 4 MB。这与最大行大小不同。如果超过了单个 JSON 对象或数组的最大大小，则即使生成的行大小未达到 4 MB 的行大小限制，COPY 命令也会失败。

在计算行大小时，Amazon Redshift 在内部对竖线字符 ( \$1 ) 计为两个字符。如果您的输入数据中包含大量竖线字符，则即使对象大小小于 4 MB，行大小也可能超过 4 MB。

COPY 会将 `\n` 作为换行符加载并且会将 `\t` 作为制表符加载。要加载反斜杠，请使用反斜杠 ( `\\` ) 对其进行转义。

COPY 将在指定的 JSON 源中搜索格式正确且有效的 JSON 对象或数组。如果 COPY 在找到可用的 JSON 结构之前遇到任何非空格字符，或在有效的 JSON 对象或数组之间遇到此类字符，COPY 将为每个实例返回错误。这些错误将计入 MAXERROR 错误计数。当错误计数等于或超过 MAXERROR 时，COPY 将失败。

对于每个错误，Amazon Redshift 都会在 STL\$1LOAD\$1ERRORS 系统表中记录一行。LINE\$1NUMBER 列将记录导致错误的 JSON 对象的最后一行。

如果指定了 IGNOREHEADER，COPY 将忽略 JSON 数据中指定数量的行。JSON 数据中的换行符始终计入到 IGNOREHEADER 计算中。

默认情况下，COPY 将空字符串作为空字段加载。如果指定了 EMPTYASNULL，COPY 会将 CHAR 和 VARCHAR 字段的空字符串作为 NULL 加载。其他数据类型（如 INT）的空字符串始终作为 NULL 加载。

不支持将以下选项与 JSON 一起使用：
+ CSV
+ DELIMITER 
+ ESCAPE
+ FILLRECORD 
+ FIXEDWIDTH
+ IGNOREBLANKLINES
+ NULL AS
+ READRATIO
+ REMOVEQUOTES 

有关更多信息，请参阅 [从 JSON 格式数据执行的 COPY 操作](copy-usage_notes-copy-from-json.md)。有关 JSON 数据结构的更多信息，请转到 [www.json.org](https://www.json.org/)。

## JSONPaths 文件
<a name="copy-json-jsonpaths"></a>

如果您正在从 JSON 格式的源数据或 Avro 源数据加载，则在预设情况下，COPY 会将源数据中的第一层数据元素映射到目标表中的列。它的操作方式是通过将名称-值对中的每个名称（即对象键）与目标表中的列的名称匹配。

如果您的列名称与对象键不匹配，或要映射到数据层次结构中的更深层次，则可以使用 JSONPaths 文件将 JSON 或 Avro 数据元素显式映射到列。JSONPaths 文件通过匹配目标表或列列表中的列顺序来将 JSON 数据元素映射到列。

JSONPaths 文件只能包含一个 JSON 对象（非数组）。JSON 对象是一个名称-值对。*对象键*（即名称-值对的名称）必须为 `"jsonpaths"`。名称-值对中的*值* 是一组 *JSONPath 表达式*。每个 JSONPath 表达式都引用 JSON 数据层次结构或 Avro schema 中的一个元素，这与 XPath 表达式引用 XML 文档中的元素相似。有关更多信息，请参阅 [JSONPath 表达式](#copy-json-jsonpath-expressions)。

要使用 JSONPaths 文件，请将 JSON 或 AVRO 关键字添加到 COPY 命令。使用以下格式指定 JSONPath 文件的 S3 桶名称和对象路径。

```
COPY tablename 
FROM 'data_source' 
CREDENTIALS 'credentials-args' 
FORMAT AS { AVRO | JSON } 's3://jsonpaths_file';
```

`s3://jsonpaths_file` 参数必须是显式引用单个文件（如 `'s3://amzn-s3-demo-bucket/jsonpaths.txt'`）的 Amazon S3 对象键。它不能是键前缀。

在某些情况下，如果您从 Amazon S3 加载，由 `jsonpaths_file` 指定的文件的前缀与由 `copy_from_s3_objectpath` 为数据文件指定的路径的前缀相同。如果是这样，COPY 会将 JSONPaths 文件作为数据文件读取并返回错误。例如，假设您的数据文件使用对象路径 `s3://amzn-s3-demo-bucket/my_data.json`，并且您的 JSONPaths 文件是 `s3://amzn-s3-demo-bucket/my_data.jsonpaths`。在这种情况下，COPY 会尝试加载 `my_data.jsonpaths` 作为数据文件。

 如果键名称是除 `"jsonpaths"` 以外的任何字符串，则 COPY 命令不会返回错误，但会忽略 *jsonpaths\$1file* 并改为使用 `'auto'` 参数。

如果出现以下任一情况，COPY 命令将失败：
+ JSON 格式不正确。
+ 存在多个 JSON 对象。
+ 对象外部存在除空格以外的任何字符。
+ 数组元素是一个空字符串或者不是一个字符串。

MAXERROR 不适用于 JSONPaths 文件。

即使指定了 [ENCRYPTED](copy-parameters-data-source-s3.md#copy-encrypted) 选项，也不得加密 JSONPaths 文件。

有关更多信息，请参阅 [从 JSON 格式数据执行的 COPY 操作](copy-usage_notes-copy-from-json.md)。

## JSONPath 表达式
<a name="copy-json-jsonpath-expressions"></a>

JSONPaths 文件使用 JSONPath 表达式将数据字段映射到目标列。每个 JSONPath 表达式对应于 Amazon Redshift 目标表中的一个列。JSONPath 数组元素的顺序必须与目标表或列列表（如果使用了列列表）中列的顺序一致。

如上所示，字段名称和值均需要使用双引号字符。引号字符必须是简单引号 (0x22)，而不能是倾斜引号或“智能”引号。

如果 JSONPath 表达式引用的对象元素在 JSON 数据中找不到，则 COPY 将尝试加载 NULL 值。如果引用的对象的格式不正确，则 COPY 将返回加载错误。

如果 JSONPath 表达式引用的数组元素在 JSON 或 Avro 数据中找不到，则 COPY 将失败并返回以下错误：`Invalid JSONPath format: Not an array or index out of range.`请从 JSONPaths 中删除在源数据中不存在的所有数组元素，并确认源数据中数组的格式正确。  

JSONPath 表达式可使用括号表示法或点表示法，但不能将两者结合使用。以下示例显示了使用括号表示法的 JSONPath 表达式。

```
{
    "jsonpaths": [
        "$['venuename']",
        "$['venuecity']",
        "$['venuestate']",
        "$['venueseats']"
    ]
}
```

以下示例显示了使用点表示法的 JSONPath 表达式。

```
{
    "jsonpaths": [
        "$.venuename",
        "$.venuecity",
        "$.venuestate",
        "$.venueseats"
    ]
}
```

在 Amazon Redshift COPY 语法的上下文中，JSONPath 表达式必须指定 JSON 或 Avro 分层数据结构中单个名称元素的显式路径。Amazon Redshift 不支持可能解析为不确定路径或多个名称元素的任何 JSONPath 元素（如通配符或筛选表达式）。

有关更多信息，请参阅 [从 JSON 格式数据执行的 COPY 操作](copy-usage_notes-copy-from-json.md)。

## 将 JSONPaths 与 Avro 数据一起使用
<a name="using-jsonpath-with-avro"></a>

以下示例显示了具有多个层次 Avro schema。

```
{
    "name": "person",
    "type": "record",
    "fields": [
        {"name": "id", "type": "int"},
        {"name": "guid", "type": "string"},
        {"name": "isActive", "type": "boolean"},
        {"name": "age", "type": "int"},
        {"name": "name", "type": "string"},
        {"name": "address", "type": "string"},
        {"name": "latitude", "type": "double"},
        {"name": "longitude", "type": "double"},
        {
            "name": "tags",
            "type": {
                        "type" : "array",
                        "name" : "inner_tags",
                        "items" : "string"
                    }
        },
        {
            "name": "friends",
            "type": {
                        "type" : "array",
                        "name" : "inner_friends",
                        "items" : {
                                    "name" : "friends_record",
                                    "type" : "record",
                                    "fields" : [
                                                 {"name" : "id", "type" : "int"},
                                                 {"name" : "name", "type" : "string"}
                                               ]
                                  }
                    }
        },
        {"name": "randomArrayItem", "type": "string"}
    ]
}
```

以下示例显示了使用 AvroPath 表达式引用前面的 schema 的 JSONPaths 文件。

```
{
    "jsonpaths": [
        "$.id",
        "$.guid",
        "$.address",
        "$.friends[0].id"
    ]
}
```

JSONPaths 示例包含以下元素：

jsonpaths  
包含 AvroPath 表达式的 JSON 对象的名称。

[ … ]  
方括号将包含路径元素的 JSON 数组括起。

\$1  
美元符号表示 Avro schema 中的根元素，即 `"fields"` 数组。

"\$1.id",  
AvroPath 表达式的目标。在此实例中，目标是 `"fields"` 数组中名为 `"id"` 的元素。表达式用逗号分隔。

"\$1.friends[0].id"  
方括号表示数组索引。JSONPath 表达式使用从零开始的索引，因此该表达式引用 `"friends"` 数组中名为 `"id"` 的第一个元素。

Avro schema 语法需要使用*内部字段* 来定义记录和数组数据类型的结构。AvroPath 表达式将会忽略内部字段。例如，字段 `"friends"` 定义了一个名为 `"inner_friends"` 的数组，该数组又定义了一个名为 `"friends_record"` 的记录。要引用字段 `"id"` 的 AvroPath 表达式可忽略额外字段以直接引用目标字段。以下 AvroPath 表达式引用了两个属于 `"friends"` 数组的字段。

```
"$.friends[0].id"
"$.friends[0].name"
```

## 列式数据格式参数
<a name="copy-parameters-columnar-data"></a>

除标准数据格式以外，COPY 支持 Amazon S3 中有关 COPY 的以下列式数据格式。支持列式中的 COPY，其中带有特定限制。有关更多信息，请参阅 [从列式数据格式中执行 COPY 操作](copy-usage_notes-copy-from-columnar.md)。

ORC  <a name="copy-orc"></a>
从使用优化的行列式 (ORC) 文件格式的文件中加载数据。

PARQUET  <a name="copy-parquet"></a>
从使用 Parquet 文件格式的文件中加载数据。

# 文件压缩参数
<a name="copy-parameters-file-compression"></a>

您可以通过指定以下参数来从压缩的数据文件加载。文件压缩参数

BZIP2   <a name="copy-bzip2"></a>
一个值，用于指定输入文件采用压缩 bzip2 格式（.bz2 文件）。COPY 操作将读取每个压缩文件并在加载时解压数据。

GZIP   <a name="copy-gzip"></a>
一个值，用于指定输入文件采用压缩 gzip 格式（.gz 文件）。COPY 操作将读取每个压缩文件并在加载时解压数据。

LZOP   <a name="copy-lzop"></a>
一个值，用于指定输入文件采用压缩 lzop 格式（.lzo 文件）。COPY 操作将读取每个压缩文件并在加载时解压数据。  
COPY 不支持使用 lzop *--filter* 选项压缩的文件。

ZSTD   <a name="copy-zstd"></a>
一个值，用于指定输入文件采用压缩 Zstandard 格式（.zst 文件）。COPY 操作将读取每个压缩文件并在加载时解压数据。  
只有从 Amazon S3 进行 COPY 操作时，才支持 ZSTD。

# 数据转换参数
<a name="copy-parameters-data-conversion"></a>

在加载表时，COPY 会尝试将源数据中的字符串隐式转换为目标列的数据类型。如果您需要指定不同于默认行为的转换，或者默认转换会产生错误，则可以通过指定以下参数来管理数据转换。有关这些参数语法的更多信息，请参阅 [COPY 语法](https://docs.aws.amazon.com/redshift/latest/dg/r_COPY.html#r_COPY-syntax)。
+ [ACCEPTANYDATE](#copy-acceptanydate) 
+ [ACCEPTINVCHARS](#copy-acceptinvchars) 
+ [BLANKSASNULL](#copy-blanksasnull) 
+ [DATEFORMAT](#copy-dateformat) 
+ [EMPTYASNULL](#copy-emptyasnull) 
+ [ENCODING](#copy-encoding) 
+ [ESCAPE](#copy-escape) 
+ [EXPLICIT_IDS](#copy-explicit-ids) 
+ [FILLRECORD](#copy-fillrecord) 
+ [IGNOREBLANKLINES](#copy-ignoreblanklines) 
+ [IGNOREHEADER](#copy-ignoreheader) 
+ [NULL AS](#copy-null-as) 
+ [REMOVEQUOTES](#copy-removequotes) 
+ [ROUNDEC](#copy-roundec) 
+ [TIMEFORMAT](#copy-timeformat) 
+ [TRIMBLANKS](#copy-trimblanks) 
+ [TRUNCATECOLUMNS](#copy-truncatecolumns) <a name="copy-data-conversion-parameters"></a>数据转换参数

ACCEPTANYDATE   <a name="copy-acceptanydate"></a>
允许加载包括无效格式（如 `00/00/00 00:00:00`）在内的任何日期格式，而不生成错误。此参数仅适用于 TIMESTAMP 和 DATE 列。始终将 ACCEPTANYDATE 与 DATEFORMAT 参数结合使用。如果数据的日期格式与 DATEFORMAT 规范不匹配，则 Amazon Redshift 会将 NULL 值插入该字段中。

ACCEPTINVCHARS [AS] ['*replacement\$1char*']   <a name="copy-acceptinvchars"></a>
允许将数据加载到 VARCHAR 列中，即使数据包含无效的 UTF-8 字符。如果指定 ACCEPTINVCHARS，则 COPY 会将每个无效的 UTF-8 字符替换为长度相等且包含由 *replacement\$1char* 指定的字符的字符串。例如，如果替换字符为“`^`”，则将使用“`^^^`”替换无效的三字节字符。  
 替换字符可以是除 NULL 之外的任何 ASCII 字符。默认值为一个问号 (?)。有关无效的 UTF-8 字符的信息，请参阅[多字节字符加载错误](multi-byte-character-load-errors.md)。  
COPY 将返回包含无效 UTF-8 字符的行的数量，并将为每个受影响的行在 [STL\$1REPLACEMENTS](r_STL_REPLACEMENTS.md) 系统表中添加一个条目，每个节点切片最多有 100 行。还将替换其他无效的 UTF-8 字符，但不会记录这些替换事件。  
如果未指定 ACCEPTINVCHARS，则 COPY 在遇到无效 UTF-8 字符时将返回错误。  
ACCEPTINVCHARS 仅对 VARCHAR 列有效。

BLANKSASNULL   <a name="copy-blanksasnull"></a>
将仅包含空格字符的空白字段作为 NULL 加载。此选项仅适用于 CHAR 和 VARCHAR 列。其他数据类型（如 INT）的空白字段始终作为 NULL 加载。例如，包含三个连续的空格字符（并且无其他字符）的字符串将作为 NULL 加载。如果不使用此选项，则默认行为是按原样加载空白字符。

DATEFORMAT [AS] \$1'*dateformat\$1string*' \$1 'auto' \$1  <a name="copy-dateformat"></a>
如果未指定 DATEFORMAT，则默认格式为 `'YYYY-MM-DD'`。例如，一种有效的替代格式为 `'MM-DD-YYYY'`。  
如果 COPY 命令未识别日期或时间值的格式，或者日期或时间值使用不同的格式，请将 `'auto'` 参数与 DATEFORMAT 或 TIMEFORMAT 参数结合使用。在使用 DATEFORMAT 和 TIMEFORMAT 字符串时，`'auto'` 参数将识别一些不受支持的格式。`'auto'` 的关键字区分大小写。有关更多信息，请参阅 [在 DATEFORMAT 和 TIMEFORMAT 中使用自动识别](automatic-recognition.md)。  
日期格式可包含时间信息（小时、分钟、秒），但此信息将被忽略。AS 关键字是可选的。有关更多信息，请参阅 [DATEFORMAT 和 TIMEFORMAT 字符串示例](r_DATEFORMAT_and_TIMEFORMAT_strings.md)。

EMPTYASNULL   <a name="copy-emptyasnull"></a>
指示 Amazon Redshift 应将空 CHAR 和 VARCHAR 字段作为 NULL 加载。其他数据类型（如 INT）的空字段始终作为 NULL 加载。当数据包含两个连续的分隔符且分隔符之间没有字符时，将出现空字段。EMPTYASNULL 和 NULL AS ''（空字符串）将产生相同的行为。

ENCODING [AS] *file\$1encoding*  <a name="copy-encoding"></a>
指定加载数据的编码类型。COPY 命令在加载过程中将数据从指定的编码转换为 UTF-8。  
*file\$1encoding* 的有效值如下所示：  
+ `UTF8`
+ `UTF16`
+ `UTF16LE`
+ `UTF16BE`
+ `ISO88591`
默认为 `UTF8`。  
源文件名必须使用 UTF-8 编码。  
下列文件必须使用 UTF-8 编码，即使为加载数据指定了不同的编码：  
+ 清单文件
+ JSONPaths 文件
随下列参数提供的参数字符串必须使用 UTF-8：  
+ FIXEDWIDTH '*fixedwidth\$1spec*'
+ ACCEPTINVCHARS '*replacement\$1char*'
+ DATEFORMAT '*dateformat\$1string*'
+ TIMEFORMAT '*timeformat\$1string*'
+ NULL AS '*null\$1string*'
固定宽度的数据文件必须使用 UTF-8 编码。字段宽度基于字符数，而不是字节数。  
所有加载数据必须使用指定编码。如果 COPY 遇到不同的编码，将跳过文件并返回错误。  
如果您指定 `UTF16`，则您的数据必须具有字节顺序标记 (BOM)。如果您知道您的 UTF-16 数据是否为 little-endian (LE) 或 big-endian (BE)，则不管是否存在 BOM，均可使用 `UTF16LE` 或 `UTF16BE`。  
要使用 ISO-8859-1 编码，请指定 `ISO88591`。有关更多信息，请参阅 *Wikipedia* 中的 [ISO/IEC 8859-1](https://en.wikipedia.org/wiki/ISO/IEC_8859-1)。

ESCAPE   <a name="copy-escape"></a>
指定此参数后，输入数据中的反斜杠字符 (`\`) 将被视为转义字符。紧跟在反斜杠字符后面的字符将作为当前列值的一部分加载到表中，即使它是通常用作特殊用途的字符。例如，您可使用此参数转义分隔符字符、引号、嵌入的换行符或转义字符本身，前提是这些字符中的任何字符是列值的合法部分。  
如果您指定 ESCAPE 参数与 REMOVEQUOTES 参数的组合，则可转义并保留可能会被删除的引号（`'` 或 `"`）。默认 null 字符串 `\N` 按原样工作，但也可在输入数据中转义为 `\\N`。只要您未使用 NULL AS 参数指定替换 null 字符串，`\N` 和 `\\N` 就会产生相同的结果。  
控制字符 `0x00` (NUL) 无法转义，应从输入数据中删除或进行转换。此字符将被视为记录结束 (EOR) 标记，并导致记录的剩余部分被截断。
您无法对 FIXEDWIDTH 加载使用 ESCAPE 参数，并且无法指定转义字符本身；转义字符始终为反斜杠字符。此外，您必须确保输入数据在合适的位置包含转义字符。  
下面是在指定 ESCAPE 参数的情况下的输入数据和产生的加载数据的一些示例。第 4 行的结果假设还指定了 REMOVEQUOTES 参数。输入数据包含两个用竖线分隔的字段：  

```
1|The quick brown fox\[newline]
jumped over the lazy dog.
2| A\\B\\C
3| A \| B \| C
4| 'A Midsummer Night\'s Dream'
```
加载到第 2 列的数据看上去与下面类似：  

```
The quick brown fox
jumped over the lazy dog.
A\B\C
A|B|C
A Midsummer Night's Dream
```
对加载的输入数据应用转义字符是用户的责任。此要求的一个例外情况是在您重新加载之前使用 ESCAPE 参数卸载的数据时。在此情况下，数据将已经包含必需的转义字符。
ESCAPE 参数不会解释 octal、hex、Unicode 或其他转义序列表示法。例如，如果您的源数据包含 octal 换行符值 (`\012`) 并且您尝试使用 ESCAPE 参数加载此数据，则 Amazon Redshift 会将值 `012` 加载到表中并且不会将此值解释为要转义的换行符。  
为了转义源自 Microsoft Windows 平台的数据中的换行符，您可能需要使用两个转义字符：一个用于回车，一个用于换行。您也可以在加载文件（例如，通过使用 dos2unix 实用工具）之前删除回车符。

EXPLICIT\$1IDS   <a name="copy-explicit-ids"></a>
如果要将表中自动生成的值替换为源数据文件中的显式值，请对具有 IDENTITY 列的表使用 EXPLICIT\$1IDS。如果命令包含一个列列表，则该列表必须包含 IDENTITY 列才能使用此参数。EXPLICIT\$1IDS 值的数据格式必须与 CREATE TABLE 定义指定的 IDENTITY 格式匹配。  
在对表运行带 EXPLICIT\$1IDS 选项的 COPY 命令时，Amazon Redshift 不会检查表中 IDENTITY 列的唯一性。  
如果某个列使用 GENERATED BY DEFAULT AS IDENTITY 进行定义，则可以复制该列。使用您提供的值生成或更新值。EXPLICIT\$1IDS 选项不是必需项。COPY 不会更新身份高级别水印。  
 有关使用 EXPLICIT\$1IDS 的 COPY 命令的示例，请参阅[加载具有显式的 IDENTITY 列值的 VENUE](r_COPY_command_examples.md#r_COPY_command_examples-load-venue-with-explicit-values-for-an-identity-column)。

FILLRECORD   <a name="copy-fillrecord"></a>
当一些记录的末尾缺少相邻列时，允许加载数据文件。将缺少的列加载为 NULL。对于文本和 CSV 格式，如果缺少的是 VARCHAR 列，则会加载零长度字符串而非 NULL。要从文本和 CSV 将 NULL 加载到 VARCHAR 列，请指定 EMPTYASNULL 关键字。仅当列定义允许 NULL 时，NULL 替换才会工作。  
例如，如果表定义包含 4 个可以为 null 的 CHAR 列，并且记录包含值 `apple, orange, banana, mango`，则 COPY 命令可能加载并填充仅包含 `apple, orange` 值的记录。缺少的 CHAR 值将作为 NULL 值加载。

IGNOREBLANKLINES   <a name="copy-ignoreblanklines"></a>
忽略数据文件中仅包含换行符的空行并且不尝试加载它们。

IGNOREHEADER [ AS ] *number\$1rows*   <a name="copy-ignoreheader"></a>
将指定的 *number\$1rows* 视为文件标题并且不加载它们。使用 IGNOREHEADER 跳过并行加载的所有文件中的文件标题。

NULL AS '*null\$1string*'  <a name="copy-null-as"></a>
加载将 *null\$1string* 匹配为 NULL 的字段，其中 *null\$1string* 可以是任何字符串。如果您的数据包含 null 终止符（也称为 NUL (UTF-8 0000) 或二进制零 (0x000)），则 COPY 会将其视为任何其他字符。例如，包含 '1' \$1\$1 NUL \$1\$1 '2' 的记录被复制为长度为 3 个字节的字符串。如果字段仅包含 NUL，您可使用 NULL AS 通过指定 `'\0'` 或 `'\000'` 来将 null 终止符替换为 NULL，例如，`NULL AS '\0'` 或 `NULL AS '\000'`。如果指定包含以 NUL 和 NULL AS 结尾的字符串的字段，则将在末尾处插入 NUL。请勿将“\$1n”（换行符）用于 *null\$1string* 值。Amazon Redshift 将保留“\$1n”以用作行分隔符。默认 *null\$1string* 为 `'\N`'。  
如果您尝试将 null 加载到定义为 NOT NULL 的列中，则 COPY 命令将失败。

REMOVEQUOTES   <a name="copy-removequotes"></a>
删除传入数据中的字符串周围的引号。将保留引号中的所有字符（包括分隔符）。如果字符串具有开始单引号或双引号但没有对应的结束引号，则 COPY 命令将无法加载相应行并返回错误。下表显示了包含引号的字符串和最终加载值的一些简单示例。      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/copy-parameters-data-conversion.html)

ROUNDEC   <a name="copy-roundec"></a>
当输入值的小数位数超出列的小数位数时，会将数值向上取整。默认情况下，COPY 将在必要时截断值以匹配列的小数位数。例如，如果将值 `20.259` 加载到 DECIMAL(8,2) 列中，则 COPY 默认情况下会将此值截断为 `20.25`。如果指定 ROUNDEC，则 COPY 会将值取整为 `20.26`。INSERT 命令始终在必要时将值取整以匹配列的小数位数，因此包含 ROUNDEC 参数的 COPY 命令的行为方式与 INSERT 命令相同。

TIMEFORMAT [AS] \$1'*timeformat\$1string*' \$1 'auto' \$1 'epochsecs' \$1 'epochmillisecs' \$1  <a name="copy-timeformat"></a>
指定时间格式。如果未指定 TIMEFORMAT，则默认格式为 `YYYY-MM-DD HH:MI:SS`（对于 TIMESTAMP 列）或 `YYYY-MM-DD HH:MI:SSOF`（对于 TIMESTAMPTZ 列），其中 `OF` 是与协调世界时 (UTC) 的时差。您不能在 *timeformat\$1string* 中包括时区标识符。要加载格式与默认格式不同的 TIMESTAMPTZ 数据，请指定“自动”；有关更多信息，请参阅 [在 DATEFORMAT 和 TIMEFORMAT 中使用自动识别](automatic-recognition.md)。有关 *timeformat\$1string* 的更多信息，请参阅 [DATEFORMAT 和 TIMEFORMAT 字符串示例](r_DATEFORMAT_and_TIMEFORMAT_strings.md)。  
在使用 DATEFORMAT 和 TIMEFORMAT 字符串时，`'auto'` 参数将识别一些不受支持的格式。如果 COPY 命令未识别日期或时间值的格式，或者日期和时间值使用不同的格式，请将 `'auto'` 参数与 DATEFORMAT 或 TIMEFORMAT 参数结合使用。有关更多信息，请参阅 [在 DATEFORMAT 和 TIMEFORMAT 中使用自动识别](automatic-recognition.md)。  
如果源数据以纪元时间（自 1970 年 1 月 1 日 00:00:00 UTC 以来的秒数或微秒数）表示，请指定 `'epochsecs'` 或 `'epochmillisecs'`。  
`'auto'`、`'epochsecs'` 和 `'epochmillisecs'` 关键字区分大小写。  
AS 关键字是可选的。

TRIMBLANKS   <a name="copy-trimblanks"></a>
删除 VARCHAR 字符串的尾部空格字符。此参数仅适用于具有 VARCHAR 数据类型的列。

TRUNCATECOLUMNS   <a name="copy-truncatecolumns"></a>
将列中的数据截断为合适的字符数以符合列规范。仅适用于具有 VARCHAR 或 CHAR 数据类型的列以及大小为 4 MB 或以下的行。

# 数据加载操作
<a name="copy-parameters-data-load"></a>

通过指定以下参数来管理加载操作的默认行为，以进行故障排除或缩短加载时间。
+ [COMPROWS](#copy-comprows) 
+ [COMPUPDATE](#copy-compupdate) 
+ [IGNOREALLERRORS](#copy-ignoreallerrors) 
+ [MAXERROR](#copy-maxerror) 
+ [NOLOAD](#copy-noload) 
+ [STATUPDATE](#copy-statupdate) <a name="copy-data-load-parameters"></a>参数

COMPROWS *numrows*   <a name="copy-comprows"></a>
指定要用作压缩分析的样本大小的行数。将对来自每个数据切片的行运行分析。例如，如果指定 `COMPROWS 1000000` (1000000) 且系统总共包含 4 个切片，则将为每个切片读取和分析的行数不超过 250000。  
如果未指定 COMPROWS，则每个切片的样本大小默认为 100000。小于每个切片 100000 行这一默认值的 COMPROWS 值将自动升级到此默认值。但是，如果加载的数据量不足以生成有意义的样本，则不会执行自动压缩。  
如果 COMPROWS 数量大于输入文件中的行数，则 COPY 命令仍将继续并对所有可用行运行压缩分析。此参数接受的范围介于 1000 到 2147483647 (2,147,483,647) 之间。

COMPUPDATE [ PRESET \$1 \$1 ON \$1 TRUE \$1 \$1 \$1 OFF \$1 FALSE \$1 ]  <a name="copy-compupdate"></a>
控制是否在 COPY 期间自动应用压缩编码。  
如果 COMPUPDATE 为 PRESET，则在目标表为空时，COPY 命令会为每个列选择压缩编码，即使列已经有除 RAW 之外的编码也不例外。可以替换当前指定的列编码。每个列的编码基于列数据类型。不会对数据进行采样。Amazon Redshift 自动分配压缩编码，如下所示：  
+ 为定义为排序键的列分配 RAW 压缩。
+ 为定义为 BOOLEAN、REAL 或 DOUBLE PRECISION 数据类型的列分配 RAW 压缩。
+ 定义为 SMALLINT、INTEGER、BIGINT、DECIMAL、DATE、TIMESTAMP 或 TIMESTAMPTZ 的列分配了 AZ64 压缩。
+ 定义为 CHAR 或 VARCHAR 的列分配了 LZO 压缩。
如果省略了 COMPUPDATE，只有在目标表为空并且您没有为任何列指定编码（而非 RAW）时，COPY 命令才会为每个列选择压缩编码。每个列的编码是由 Amazon Redshift 确定的。不会对数据进行采样。  
如果 COMPUPDATE 为 ON（或 TRUE）或者指定 COMPUPDATE 而没有提供选项，在表为空时，COPY 命令将应用自动压缩，即使表列已具有除 RAW 以外的编码。可以替换当前指定的列编码。每个列的编码基于样本数据分析。有关更多信息，请参阅 [使用自动压缩加载表](c_Loading_tables_auto_compress.md)。  
在 COMPUPDATE 为 OFF（或 FALSE）时，将禁用自动压缩。不会更改列编码。  
有关分析压缩的系统表的信息，请参阅 [STL\$1ANALYZE\$1COMPRESSION](r_STL_ANALYZE_COMPRESSION.md)。

IGNOREALLERRORS   <a name="copy-ignoreallerrors"></a>
您可以指定此选项来忽略加载操作期间出现的所有错误。  
如果您指定了 MAXERROR 选项，则无法指定 IGNOREALLERRORS 选项。不能为列式格式（包括 ORC 和 Parquet）指定 IGNOREALLERRORS 选项。

MAXERROR [AS] *error\$1count*   <a name="copy-maxerror"></a>
如果加载操作返回 *error\$1count* 数量的错误或更多错误，加载将失败。如果加载操作返回较少的错误，则将继续并返回指示无法加载的行数的 INFO 消息。使用此参数可允许加载操作在某些行因为格式设置错误或数据中的其他不一致性而未能加载到表中时继续。  
如果您希望加载操作在出现第一个错误时就失败，请将此值设置为 `0` 或 `1`。AS 关键字是可选的。MAXERROR 默认值为 `0`，限制值为 `100000`。  
 由于 Amazon Redshift 的并行处理特性，报告的实际错误数量可能高出指定的 MAXERROR。如果 Amazon Redshift 集群中的任何节点检测到已超出 MAXERROR，则每个节点将报告它遇到的所有错误。

NOLOAD   <a name="copy-noload"></a>
检查数据文件的有效性，而不用实际加载数据。通过使用 NOLOAD 参数，可以在运行实际数据加载之前，确保数据文件加载而不产生任何错误。将 COPY 与 NOLOAD 参数结合运行将比加载数据要快很多，因为前者仅分析文件。

STATUPDATE [ \$1 ON \$1 TRUE \$1 \$1 \$1 OFF \$1 FALSE \$1 ]  <a name="copy-statupdate"></a>
在成功的 COPY 命令结束时，控制对优化器统计数据的自动计算和刷新。默认情况下，如果未使用 STATUPDATE 参数，则将在表最初为空时自动更新统计数据。  
将数据插入非空表中将明显更改表的大小，我们建议通过运行 [ANALYZE](r_ANALYZE.md) 命令或使用 STATUPDATE ON 参数来更新统计数据。  
使用 STATUPDATE ON（或 TRUE），不管表最初是否为空，都将自动更新统计数据。如果使用 STATUPDATE，则当前用户必须是表所有者或超级用户。如果未指定 STATUPDATE，则仅需要 INSERT 权限。  
通过使用 STATUPDATE OFF（或 FALSE），将从不更新统计数据。  
有关更多信息，请参阅[分析表](t_Analyzing_tables.md)。

# 按字母顺序排列的参数列表
<a name="r_COPY-alphabetical-parm-list"></a>

以下列表提供指向每个 COPY 命令参数（按字母顺序排列）的描述的链接。
+ [ACCEPTANYDATE](copy-parameters-data-conversion.md#copy-acceptanydate)
+ [ACCEPTINVCHARS](copy-parameters-data-conversion.md#copy-acceptinvchars)
+ [ACCESS\$1KEY\$1ID、SECRET\$1ACCESS\$1KEY](copy-parameters-authorization.md#copy-access-key-id-access)
+ [AVRO](copy-parameters-data-format.md#copy-avro)
+ [BLANKSASNULL](copy-parameters-data-conversion.md#copy-blanksasnull)
+ [BZIP2](copy-parameters-file-compression.md#copy-bzip2) 
+ [COMPROWS](copy-parameters-data-load.md#copy-comprows)
+ [COMPUPDATE](copy-parameters-data-load.md#copy-compupdate)
+ [CREDENTIALS](copy-parameters-authorization.md#copy-credentials-cred)
+ [CSV](copy-parameters-data-format.md#copy-csv)
+ [DATEFORMAT](copy-parameters-data-conversion.md#copy-dateformat)
+ [DELIMITER](copy-parameters-data-format.md#copy-delimiter)
+ [EMPTYASNULL](copy-parameters-data-conversion.md#copy-emptyasnull)
+ [ENCODING](copy-parameters-data-conversion.md#copy-encoding)
+ [ENCRYPTED](copy-parameters-data-source-s3.md#copy-encrypted)
+ [ESCAPE](copy-parameters-data-conversion.md#copy-escape)
+ [EXPLICIT_IDS](copy-parameters-data-conversion.md#copy-explicit-ids)
+ [FILLRECORD](copy-parameters-data-conversion.md#copy-fillrecord)
+ [FIXEDWIDTH](copy-parameters-data-format.md#copy-fixedwidth)
+ [FORMAT](copy-parameters-data-format.md#copy-format)
+ [FROM](copy-parameters-data-source-s3.md#copy-parameters-from)
+ [GZIP](copy-parameters-file-compression.md#copy-gzip)
+ [IAM\$1ROLE](copy-parameters-authorization.md#copy-iam-role-iam)
+ [IGNOREALLERRORS](copy-parameters-data-load.md#copy-ignoreallerrors)
+ [IGNOREBLANKLINES](copy-parameters-data-conversion.md#copy-ignoreblanklines)
+ [IGNOREHEADER](copy-parameters-data-conversion.md#copy-ignoreheader)
+ [JSON format for COPY](copy-parameters-data-format.md#copy-json)
+ [LZOP](copy-parameters-file-compression.md#copy-lzop)
+ [MANIFEST](copy-parameters-data-source-s3.md#copy-manifest)
+ [MASTER_SYMMETRIC_KEY](copy-parameters-data-source-s3.md#copy-master-symmetric-key)
+ [MAXERROR](copy-parameters-data-load.md#copy-maxerror)
+ [NOLOAD](copy-parameters-data-load.md#copy-noload)
+ [NULL AS](copy-parameters-data-conversion.md#copy-null-as)
+ [READRATIO](copy-parameters-data-source-dynamodb.md#copy-readratio)
+ [REGION](copy-parameters-data-source-s3.md#copy-region)
+ [REMOVEQUOTES](copy-parameters-data-conversion.md#copy-removequotes)
+ [ROUNDEC](copy-parameters-data-conversion.md#copy-roundec)
+ [SESSION\$1TOKEN](copy-parameters-authorization.md#copy-token)
+ [SHAPEFILE](copy-parameters-data-format.md#copy-shapefile)
+ [SSH](copy-parameters-data-source-ssh.md#copy-ssh)
+ [STATUPDATE](copy-parameters-data-load.md#copy-statupdate)
+ [TIMEFORMAT](copy-parameters-data-conversion.md#copy-timeformat)
+ [TRIMBLANKS](copy-parameters-data-conversion.md#copy-trimblanks)
+ [TRUNCATECOLUMNS](copy-parameters-data-conversion.md#copy-truncatecolumns)
+ [ZSTD](copy-parameters-file-compression.md#copy-zstd)

# 使用说明
<a name="r_COPY_usage_notes"></a>

**Topics**
+ [访问其他 AWS 资源的权限](copy-usage_notes-access-permissions.md)
+ [将 COPY 与 Amazon S3 接入点别名一起使用](copy-usage_notes-s3-access-point-alias.md)
+ [从 Amazon S3 中加载多字节数据](copy-usage_notes-multi-byte.md)
+ [加载 GEOMETRY 或 GEOGRAPHY 数据类型的列](copy-usage_notes-spatial-data.md)
+ [加载 HLLSKETCH 数据类型](copy-usage_notes-hll.md)
+ [加载 VARBYTE 数据类型的列](copy-usage-varbyte.md)
+ [在读取多个文件时出现错误](copy-usage_notes-multiple-files.md)
+ [从 JSON 格式数据执行的 COPY 操作](copy-usage_notes-copy-from-json.md)
+ [从列式数据格式中执行 COPY 操作](copy-usage_notes-copy-from-columnar.md)
+ [DATEFORMAT 和 TIMEFORMAT 字符串](r_DATEFORMAT_and_TIMEFORMAT_strings.md)
+ [在 DATEFORMAT 和 TIMEFORMAT 中使用自动识别](automatic-recognition.md)

# 访问其他 AWS 资源的权限
<a name="copy-usage_notes-access-permissions"></a>

 要在您的集群和其他 AWS 资源（如 Amazon S3 、Amazon DynamoDB、Amazon EMR 或 Amazon EC2）之间移动数据，您的集群必须具有访问相应资源和执行所需操作的权限。例如，要从 Amazon S3 加载数据，COPY 必须具有对桶的 LIST 访问权限以及对桶对象的 GET 访问权限。有关最低权限的更多信息，请参阅 [COPY、UNLOAD 和 CREATE LIBRARY 的 IAM 权限](#copy-usage_notes-iam-permissions)。

要获取访问资源的授权，您的集群必须经过身份验证。您可以选择以下身份验证方法之一：
+ [基于角色的访问控制](#copy-usage_notes-access-role-based) – 对于基于角色的访问控制，您指定您的集群用于身份验证和授权的 AWS Identity and Access Management (IAM) 角色。为了保护您的 AWS 凭证和敏感数据，我们强烈建议使用基于角色的身份验证。
+ [基于密钥的访问控制](#copy-usage_notes-access-key-based) – 对于基于密钥的访问控制，您以纯文本形式为用户提供 AWS 访问凭证（访问密钥 ID 和秘密访问密钥）。

## 基于角色的访问控制
<a name="copy-usage_notes-access-role-based"></a>

利用<a name="copy-usage_notes-access-role-based.phrase"></a>基于角色的访问控制，您的集群将代表您临时代入 IAM 角色。然后，基于对角色的授权，您的集群可访问所需的 AWS 资源。

创建 IAM *角色*类似于向用户授予权限，因为它是一个 AWS 身份，具有确定该身份在 AWS 中可执行和不可执行的操作的权限策略。但是，任何实体都可以根据需要代入某个角色，角色并不是唯一地与某个用户关联。此外，角色没有任何关联的凭证（密码或访问密钥）。相反，如果将角色与集群关联，则会动态创建访问密钥并将其提供给集群。

我们建议使用基于角色的访问控制，因为除了保护您的 AWS 凭证之外，它还将提供对 AWS 资源和敏感用户数据的更安全、精细的访问控制。

基于角色的身份验证具有以下优点：
+ 您可以使用 AWS 标准 IAM 工具定义 IAM 角色并将该角色与多个集群关联。当您修改某个角色的访问策略时，更改将自动应用于使用该角色的所有集群。
+ 您可定义为特定集群和数据库用户授予对特定 AWS 资源和操作的访问权限的精细 IAM 策略。
+ 您的集群将在运行时获取临时会话凭证并按需刷新凭证直到操作完成。如果您使用了基于密钥的临时凭证，并且临时凭证在操作完成前到期，操作将失败。
+ 您的访问密钥 ID 和秘密访问密钥 ID 不会在 SQL 代码中存储或传输。

要使用基于角色的访问控制，您必须先使用 Amazon Redshift 服务角色类型创建 IAM 角色，然后将此角色附加到您的集群。此角色至少必须具有 [COPY、UNLOAD 和 CREATE LIBRARY 的 IAM 权限](#copy-usage_notes-iam-permissions)中列出的权限。有关创建 IAM 角色并将其附加到集群的步骤，请参阅《Amazon Redshift 管理指南》**中的[授权 Amazon Redshift 代表您访问其它 AWS 服务](https://docs.aws.amazon.com/redshift/latest/mgmt/authorizing-redshift-service.html)。

通过使用 Amazon Redshift 管理控制台、CLI 或 API，您可将角色添加到集群或查看与集群关联的角色。有关更多信息，请参阅《Amazon Redshift 管理指南》**中的[将 IAM 角色与集群关联](https://docs.aws.amazon.com/redshift/latest/mgmt/copy-unload-iam-role.html)。

当您创建 IAM 角色时，IAM 将返回该角色的 Amazon 资源名称 (ARN)。要指定 IAM 角色，请利用 [使用 IAM\$1ROLE 参数](copy-parameters-authorization.md#copy-iam-role) 参数或 [使用 CREDENTIALS 参数](copy-parameters-authorization.md#copy-credentials) 参数提供角色 ARN。

例如，假设以下角色已附加到集群。

```
"IamRoleArn": "arn:aws:iam::0123456789012:role/MyRedshiftRole"
```

以下 COPY 命令示例使用 IAM\$1ROLE 参数，其 ARN 在上一示例中用于身份验证和访问 Amazon S3。

```
copy customer from 's3://amzn-s3-demo-bucket/mydata'  
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

以下 COPY 命令示例使用 CREDENTIALS 参数指定 IAM 角色。

```
copy customer from 's3://amzn-s3-demo-bucket/mydata' 
credentials 
'aws_iam_role=arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

此外，超级用户还可以向数据库用户和组授予 ASSUMEROLE 权限，以便为 COPY 操作提供对角色的访问权限。有关信息，请参阅 [GRANT](r_GRANT.md)。

## 基于密钥的访问控制
<a name="copy-usage_notes-access-key-based"></a>

利用<a name="copy-usage_notes-access-key-based.phrase"></a>基于密钥的访问控制，您将为获权访问包含数据的 AWS 资源的 IAM 用户提供访问密钥 ID 和秘密访问密钥。您可以结合使用 [使用 ACCESS\$1KEY\$1ID 和 SECRET\$1ACCESS\$1KEY 参数](copy-parameters-authorization.md#copy-access-key-id) 参数或使用 [使用 CREDENTIALS 参数](copy-parameters-authorization.md#copy-credentials) 参数。

**注意**  
我们强烈建议使用 IAM 角色进行身份验证而不是提供纯文本访问密钥 ID 和秘密访问密钥。如果您选择基于密钥的访问控制，则不要使用 AWS 账户（根）凭证。应始终创建 IAM 用户并提供该用户的访问密钥 ID 和秘密访问密钥。有关创建 IAM 用户的步骤，请参阅[在您的 AWS 账户中创建 IAM 用户](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html)。

要使用 ACCESS\$1KEY\$1ID 和 SECRET\$1ACCESS\$1KEY 进行身份验证，请使用授权用户的访问密钥 ID 和完整的秘密访问密钥替换 *<access-key-id>* 和 *<secret-access-key>*，如下所示。

```
ACCESS_KEY_ID '<access-key-id>'
SECRET_ACCESS_KEY '<secret-access-key>';
```

要使用 CREDENTIALS 参数进行身份验证，请使用授权用户的访问密钥 ID 和完整的秘密访问密钥替换 *<access-key-id>* 和 *<secret-access-key>*，如下所示。

```
CREDENTIALS
'aws_access_key_id=<access-key-id>;aws_secret_access_key=<secret-access-key>';
```

IAM 用户必须至少具有 [COPY、UNLOAD 和 CREATE LIBRARY 的 IAM 权限](#copy-usage_notes-iam-permissions) 中列出的权限。

### 临时安全凭证
<a name="r_copy-temporary-security-credentials"></a>

 如果您使用基于密钥的访问控制，则可通过使用临时安全凭证进一步限制用户对您的数据具有的访问权限。基于角色的身份验证将自动使用临时凭证。

**注意**  
我们强烈建议您使用 [role-based access control](#copy-usage_notes-access-role-based.phrase)，而不要创建临时凭证并提供纯文本形式的访问密钥 ID 和秘密访问密钥。基于角色的访问控制将自动使用临时凭证。

临时安全证书可增强安全性，因为它们时效短，过期后无法重复使用。使用令牌生成的访问密钥 ID 和秘密访问密钥无法脱离令牌使用，具有这些临时安全凭证的用户仅可以在凭证未过期前访问您的资源。

要为用户授予对您的资源的临时访问权限，请调用 AWS Security Token Service (AWS STS) API 操作。AWS STS API 操作将返回临时安全凭证，其中包括一个安全令牌、一个访问密钥 ID 和一个秘密访问密钥。您为需要临时访问您的资源的用户颁发临时安全凭证。这些用户可以是现有的 IAM 用户，也可以是非 AWS 用户。有关创建临时安全凭证的更多信息，请参阅《IAM 用户指南》中的[使用临时安全凭证](https://docs.aws.amazon.com/STS/latest/UsingSTS/Welcome.html)。

您可以将 [使用 ACCESS\$1KEY\$1ID 和 SECRET\$1ACCESS\$1KEY 参数](copy-parameters-authorization.md#copy-access-key-id) 参数与 [SESSION\$1TOKEN](copy-parameters-authorization.md#copy-token) 参数或 [使用 CREDENTIALS 参数](copy-parameters-authorization.md#copy-credentials) 参数配合使用。您还必须提供随令牌一起提供的访问密钥 ID 和秘密访问密钥。

要使用 ACCESS\$1KEY\$1ID、SECRET\$1ACCESS\$1KEY 和 SESSION\$1TOKEN 进行身份验证，请根据如下所示替换 *<temporary-access-key-id>*、*<temporary-secret-access-key>* 和 *<temporary-token>*。

```
ACCESS_KEY_ID '<temporary-access-key-id>'
SECRET_ACCESS_KEY '<temporary-secret-access-key>'
SESSION_TOKEN '<temporary-token>';
```

要使用 CREDENTIALS 进行身份验证，请在凭证字符串中包括 `session_token=<temporary-token>`，如下所示。

```
CREDENTIALS
'aws_access_key_id=<temporary-access-key-id>;aws_secret_access_key=<temporary-secret-access-key>;session_token=<temporary-token>';
```

以下示例为具有临时安全凭证的 COPY 命令。

```
copy table-name
from 's3://objectpath'
access_key_id '<temporary-access-key-id>'
secret_access_key '<temporary-secret-access-key>'
session_token '<temporary-token>';
```

以下示例使用临时凭证和文件加密加载 LISTING 表。

```
copy listing
from 's3://amzn-s3-demo-bucket/data/listings_pipe.txt'
access_key_id '<temporary-access-key-id>'
secret_access_key '<temporary-secret-access-key>'
session_token '<temporary-token>'
master_symmetric_key '<root-key>'
encrypted;
```

以下示例将 CREDENTIALS 参数与临时凭证和文件加密配合使用，加载 LISTING 表。

```
copy listing
from 's3://amzn-s3-demo-bucket/data/listings_pipe.txt'
credentials 
'aws_access_key_id=<temporary-access-key-id>;aws_secret_access_key=<temporary-secret-access-key>;session_token=<temporary-token>;master_symmetric_key=<root-key>'
encrypted;
```

**重要**  
临时安全凭证必须在整个 COPY 或 UNLOAD 操作持续时间有效。如果临时安全凭证在操作过程中过期，相应命令将失败，事务将被回滚。例如，如果临时安全凭证在 15 分钟后过期而 COPY 操作需要一个小时，则 COPY 操作将失败，无法完成。如果您使用基于角色的访问，则会自动刷新临时安全凭证直到操作完成。

## COPY、UNLOAD 和 CREATE LIBRARY 的 IAM 权限
<a name="copy-usage_notes-iam-permissions"></a>

CREDENTIALS 参数引用的 IAM 角色或用户必须至少具有以下权限：
+ 对于从 Amazon S3 执行的 COPY 的操作，这是指对 Amazon S3 桶执行 LIST 以及对正在加载的 Amazon S3 对象以及清单文件（如果已使用）执行 GET 的权限。
+ 对于从 Amazon S3、Amazon EMR 执行 COPY 的操作、以及从使用 JSON 格式数据的远程主机 (SSH) 执行 COPY 的操作，这是指对 Amazon S3 上的 JSONPaths 文件（如果已使用）执行 LIST 和 GET 的权限。
+ 对于从 DynamoDB 执行 COPY 的操作，这是指对所加载的 DynamoDB 表执行 SCAN 和 DESCRIBE 的权限。
+ 对于从 Amazon EMR 集群执行的 COPY 操作，这是指对 Amazon EMR 集群上的 `ListInstances` 操作的权限。
+ 对于向 Amazon S3 执行 UNLOAD 的操作，这是指正在将数据文件卸载到的 Amazon S3 桶的 GET、LIST 和 PUT 权限。
+ 对于从 Amazon S3 执行 CREATE LIBRARY 的操作，这是指对 Amazon S3 桶执行 LIST 以及对正在导入的 Amazon S3 对象执行 GET 的权限。

**注意**  
如果您在运行 COPY、UNLOAD 或 CREATE LIBRARY 命令时收到错误消息 `S3ServiceException: Access Denied`，则您的集群对于 Amazon S3 没有适当的访问权限。

您可以通过向附加到集群的 IAM 角色、向用户或向用户所属的组附加 IAM 策略，来管理 IAM 权限。例如，`AmazonS3ReadOnlyAccess` 托管策略可授予对 Amazon S3 资源的 LIST 和 GET 权限。有关 IAM 策略的更多信息，请参阅《IAM 用户指南》**中的[管理 IAM 策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage.html)。

# 将 COPY 与 Amazon S3 接入点别名一起使用
<a name="copy-usage_notes-s3-access-point-alias"></a>

COPY 支持 Amazon S3 接入点别名。有关更多信息，请参阅《Amazon Simple Storage Service 用户指南》**中的[为您的接入点使用存储桶式别名](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-points-alias.html)。

# 从 Amazon S3 中加载多字节数据
<a name="copy-usage_notes-multi-byte"></a>

如果您的数据包含非 ASCII 多字节字符（例如中文或西里尔语字符），则必须将该数据加载到 VARCHAR 列。VARCHAR 数据类型支持四字节的 UTF-8 字符，而 CHAR 数据类型仅接受单字节的 ASCII 字符。您不能将五字节或更长的字符加载到 Amazon Redshift 表中。有关更多信息，请参阅 [多字节字符](c_Supported_data_types.md#c_Supported_data_types-multi-byte-characters)。

# 加载 GEOMETRY 或 GEOGRAPHY 数据类型的列
<a name="copy-usage_notes-spatial-data"></a>

您可以从字符分隔文本文件（如 CSV 文件）中的数据执行对 `GEOMETRY` 或 `GEOGRAPHY` 列的 COPY 操作。数据必须采用已知二进制（WKB 或 EWKB）格式或已知文本（WKT 或 EWKT）格式的十六进制格式，并且符合 COPY 命令的单个输入行的最大大小范围要求。有关更多信息，请参阅 [COPY](r_COPY.md)。

有关如何从 shapefile 加载的信息，请参阅[将 shapefile 加载到 Amazon Redshift](spatial-copy-shapefile.md)。

有关 `GEOMETRY` 或 `GEOGRAPHY` 数据类型的更多信息，请参阅[在 Amazon Redshift 中查询空间数据](geospatial-overview.md)。

# 加载 HLLSKETCH 数据类型
<a name="copy-usage_notes-hll"></a>

您只能以 Amazon Redshift 支持的稀疏或密集格式复制 HLL 草图。要在 HyperLogLog 草图上使用 COPY 命令，请对密集 HyperLogLog 草图使用 Base64 格式，对稀疏 HyperLogLog 草图使用 JSON 格式。有关更多信息，请参阅 [HyperLogLog 函数](hyperloglog-functions.md)。

以下示例使用 CREATE TABLE 和 COPY 将 CSV 文件中的数据导入到表中。首先，该示例使用 CREATE TABLE 创建表 `t1`。

```
CREATE TABLE t1 (sketch hllsketch, a bigint);
```

然后，它使用 COPY 将 CSV 文件中的数据导入到表 `t1` 中。

```
COPY t1 FROM s3://amzn-s3-demo-bucket/unload/' IAM_ROLE 'arn:aws:iam::0123456789012:role/MyRedshiftRole' NULL AS 'null' CSV;
```

# 加载 VARBYTE 数据类型的列
<a name="copy-usage-varbyte"></a>

您可以从 CSV、Parquet 和 ORC 格式的文件加载数据。对于 CSV，从以十六进制表示 VARBYTE 数据的文件中加载数据。你无法使用 `FIXEDWIDTH` 选项加载 VARBYTE 数据。不支持 COPY 的 `ADDQUOTES` 或 `REMOVEQUOTES` 选项。不可将 VARBYTE 列用作分区列。

# 在读取多个文件时出现错误
<a name="copy-usage_notes-multiple-files"></a>

COPY 命令是原子和事务性的。换言之，甚至在 COPY 命令读取多个文件中的数据时，整个过程也将视为单个事务。如果 COPY 在读取某个文件时遇到错误，则将自动重试直至此过程超时（请参阅[statement\$1timeout](r_statement_timeout.md)），或者如果在较长时间（15 到 30 分钟）内无法从 Amazon S3 下载数据，则将确保一次仅下载一个文件。如果 COPY 命令失败，则将取消整个事务并回滚所有更改。有关处理加载错误的更多信息，请参阅[解决数据加载问题](t_Troubleshooting_load_errors.md)。

在成功启动 COPY 命令后，此命令不会在会话终止（例如客户端断开）时失败。但是，如果 COPY 命令位于因会话终止而未完成的 BEGIN … END 事务数据块中，则整个事务（包括 COPY）都将回滚。有关事务的更多信息，请参阅 [BEGIN](r_BEGIN.md)。

# 从 JSON 格式数据执行的 COPY 操作
<a name="copy-usage_notes-copy-from-json"></a>

JSON 数据结构由一组对象 或数组 组成。JSON *对象* 以大括号开头和结尾，并包含名称-值对的无序集合。每个名称和值由冒号分隔，而每个名称/值对由逗号分隔。名称是用双引号括起的字符串。引号字符必须是简单引号 (0x22)，而不能是倾斜引号或“智能”引号。

JSON *数组* 以中括号开头和结尾，并包含由逗号分隔的值的有序集合。值可以是用双引号括起的字符串、数字、布尔值 true 或 false、null、JSON 对象或数组。

JSON 对象和数组可以嵌套，从而实现分层的数据结构。以下示例显示了包含两个有效对象的 JSON 数据结构。

```
{
    "id": 1006410,
    "title": "Amazon Redshift Database Developer Guide"
}
{
    "id": 100540,
    "name": "Amazon Simple Storage Service User Guide"
}
```

下面显示了与两个 JSON 数组相同的数据。

```
[
    1006410,
    "Amazon Redshift Database Developer Guide"
]
[
    100540,
    "Amazon Simple Storage Service User Guide"
]
```

## JSON 的 COPY 选项
<a name="copy-usage-json-options"></a>

将 COPY 与 JSON 格式数据结合使用时，可以指定以下选项：
+ `'auto' ` – COPY 自动从 JSON 文件加载字段。
+ `'auto ignorecase'` – COPY 自动从 JSON 文件加载字段，同时忽略字段名称的大小写。
+ `s3://jsonpaths_file` – COPY 使用 JSONPaths 文件解析 JSON 源数据。*JSONPaths 文件* 是一个包含单个 JSON 对象的文本文件，其中的对象名称 `"jsonpaths"` 与 JSONPath 表达式数组配对。如果该名称是 `"jsonpaths"` 之外的任何字符串，则 COPY 将使用 `'auto'` 参数而不是使用 JSONPaths 文件。

有关说明如何使用 `'auto'`、`'auto ignorecase'` 或 JSONPaths 文件以及使用 JSON 对象或数组加载数据的示例，请参阅[从 JSON 中复制的示例](r_COPY_command_examples.md#r_COPY_command_examples-copy-from-json)。

## JSONPath 选项
<a name="copy-usage-json-options"></a>

在 Amazon Redshift COPY 语法中，JSONPath 表达式使用括号表示法或点表示法指定 JSON 层次数据结构中单个名称元素的显式路径。Amazon Redshift 不支持可能解析为不确定路径或多个名称元素的任何 JSONPath 元素（如通配符或筛选表达式）。因此，Amazon Redshift 无法解析复杂、多级的数据结构。

下面是包含使用括号表示法的 JSONPath 表达式的 JSONPaths 文件的示例。美元符号 (\$1) 表示根级别结构。

```
{
    "jsonpaths": [
       "$['id']",
       "$['store']['book']['title']",
	"$['location'][0]" 
    ]
}
```

 在上面的示例中，`$['location'][0]` 引用数组中的第一个元素。JSON 使用从 0 开始的数组索引。数组索引必须是正整数（大于或等于零）。

以下示例显示了使用点表示法的前一个 JSONPaths 文件。

```
{
    "jsonpaths": [
       "$.id",
       "$.store.book.title",
	"$.location[0]"
    ]
}
```

您不能在 `jsonpaths` 数组中将括号表示法和点表示法混合。括号表示法和点表示法中均可使用括号来引用数组元素。

使用点表示法时，JSONPath 表达式不能包含下列字符：
+ 单直引号 ( ' ) 
+ 句点或点 (.) 
+ 中括号 ( [ ] )（除非用于引用数组元素） 

如果 JSONPath 表达式引用的名称-值对中的值是对象或数组，则整个对象或数组将作为字符串加载，包括大括号或中括号。例如，假定 JSON 数据包含以下对象。

```
{
    "id": 0,
    "guid": "84512477-fa49-456b-b407-581d0d851c3c",
    "isActive": true,
    "tags": [
        "nisi",
        "culpa",
        "ad",
        "amet",
        "voluptate",
        "reprehenderit",
        "veniam"
    ],
    "friends": [
        {
            "id": 0,
            "name": "Martha Rivera"
        },
        {
            "id": 1,
            "name": "Renaldo"
        }
    ]
}
```

JSONPath 表达式 `$['tags']` 之后将返回以下值。

```
"["nisi","culpa","ad","amet","voluptate","reprehenderit","veniam"]" 
```

JSONPath 表达式 `$['friends'][1]` 之后将返回以下值。

```
"{"id": 1,"name": "Renaldo"}" 
```

`jsonpaths` 数组中的每个 JSONPath 表达式对应于 Amazon Redshift 目标表中的一个列。`jsonpaths` 数组元素的顺序必须与目标表或列列表（如果使用了列列表）中列的顺序一致。

有关说明如何使用 `'auto'` 参数或 JSONPaths 文件以及使用 JSON 对象或数组加载数据的示例，请参阅[从 JSON 中复制的示例](r_COPY_command_examples.md#r_COPY_command_examples-copy-from-json)。

有关如何复制多个 JSON 文件的信息，请参阅[使用清单指定数据文件](loading-data-files-using-manifest.md)。

## 在 JSON 中转义字符
<a name="copy-usage-json-escape-characters"></a>

COPY 会将 `\n` 作为换行符加载并且会将 `\t` 作为制表符加载。要加载反斜杠，请使用反斜杠 ( `\\` ) 对其进行转义。

例如，假设您在桶 `escape.json` 中名为 `s3://amzn-s3-demo-bucket/json/` 的文件中具有以下 JSON。

```
{
  "backslash": "This is a backslash: \\",
  "newline": "This sentence\n is on two lines.",
  "tab": "This sentence \t contains a tab."
}
```

运行下列命令以创建 ESCAPES 表并加载 JSON。

```
create table escapes (backslash varchar(25), newline varchar(35), tab varchar(35));

copy escapes from 's3://amzn-s3-demo-bucket/json/escape.json' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
format as json 'auto';
```

查询 ESCAPES 表以查看结果。

```
select * from escapes;

       backslash        |      newline      |               tab
------------------------+-------------------+----------------------------------
 This is a backslash: \ | This sentence     | This sentence    contains a tab.
                        :  is on two lines.
(1 row)
```

## 数值精度丢失
<a name="copy-usage-json-rounding"></a>

当您将数字从 JSON 格式的数据文件加载到定义为数字数据类型的列时，您可能会丢失精度。某些浮点值在计算机系统中无法准确表示。因此，您从 JSON 文件复制的数据可能无法按预期进行舍入。为避免精度丢失，我们建议使用以下替代方法之一：
+ 通过用双引号字符将值括起来将数字表示为字符串。
+ 使用 [ROUNDEC](copy-parameters-data-conversion.md#copy-roundec) 对数字进行舍入而不是截断。
+ 不要使用 JSON 或 Avro 文件，而应使用 CSV、字符分隔或固定宽度的文本文件。

# 从列式数据格式中执行 COPY 操作
<a name="copy-usage_notes-copy-from-columnar"></a>

COPY 可采用以下列式格式从 Amazon S3 中加载数据：
+ ORC
+ Parquet

有关从列式数据格式中使用 COPY 的示例，请参阅[COPY 示例](r_COPY_command_examples.md)。

COPY 支持列式数据，但要注意以下几点：
+ Amazon S3 桶必须与 Amazon Redshift 数据库位于同一 AWS 区域。
+ 要通过 VPC 端点访问您的 Amazon S3 数据，请使用 IAM 策略和 IAM 角色设置访问权限，如《Amazon Redshift 管理指南》**中的[将 Amazon Redshift Spectrum 与增强 VPC 路由结合使用](https://docs.aws.amazon.com/redshift/latest/mgmt/spectrum-enhanced-vpc.html)中所述。
+ COPY 不自动应用压缩编码。
+ 仅支持以下 COPY 参数：
  + [ACCEPTINVCHARS](copy-parameters-data-conversion.md#copy-acceptinvchars)（从 ORC 或 Parquet 文件中复制时）。
  + [FILLRECORD](copy-parameters-data-conversion.md#copy-fillrecord)
  + [FROM](copy-parameters-data-source-s3.md#copy-parameters-from)
  + [IAM\$1ROLE](copy-parameters-authorization.md#copy-iam-role)
  + [CREDENTIALS](copy-parameters-authorization.md#copy-credentials)
  + [STATUPDATE ](copy-parameters-data-load.md#copy-statupdate)
  + [MANIFEST](copy-parameters-data-source-s3.md#copy-manifest)
  + [EXPLICIT\$1IDS](copy-parameters-data-conversion.md#copy-explicit-ids)
+ 如果 COPY 在加载时遇到错误，则命令失败。列式数据类型不支持 ACCEPTANYDATE 和 MAXERROR。
+ 错误消息发送至 SQL 客户端。一些错误记录在 STL\$1LOAD\$1ERRORS 和 STL\$1ERROR 中。
+ COPY 会按列在列式数据文件中出现的相同顺序将值插入到目标表的列中。目标表中的列数和数据文件中的列数必须匹配。
+ 如果您为 COPY 操作指定的文件包含下列扩展名之一，我们将解压缩数据，而无需添加任何参数：
  + `.gz`
  + `.snappy`
  + `.bz2`
+ 从 Parquet 和 ORC 文件格式的 COPY 操作使用 Redshift Spectrum 和桶访问。要对这些格式执行 COPY 操作，请确保没有任何阻止使用 Amazon S3 预签名 URL 的 IAM 策略。Amazon Redshift 生成的预签名 URL 有效期为 1 小时，这样 Amazon Redshift 就有足够的时间从 Amazon S3 存储桶中加载所有文件。COPY 操作从列式数据格式中扫描的每个文件都会生成一个唯一的预签名 URL。对于包含 `s3:signatureAge` 操作的存储桶策略，请确保将该值至少设置为 3,600,000 毫秒。有关更多信息，请参阅[将 Amazon Redshift Spectrum 与增强型 VPC 路由结合使用](https://docs.aws.amazon.com/redshift/latest/mgmt/spectrum-enhanced-vpc.html)。
+ 列式数据格式的 COPY 不支持 REGION 参数。即使 Amazon S3 存储桶和数据库位于同一 AWS 区域中，也可能会遇到错误，例如，基于 PARQUET 的 COPY 不支持 Region 参数。
+ 从列格式执行 COPY 操作现在支持并发扩展。要启用并发扩展，请参阅[配置并发扩展队列](https://docs.aws.amazon.com/redshift/latest/dg/concurrency-scaling.html#concurrency-scaling-queues)。

# DATEFORMAT 和 TIMEFORMAT 字符串
<a name="r_DATEFORMAT_and_TIMEFORMAT_strings"></a>

COPY 命令使用 DATEFORMAT 和 TIMEFORMAT 选项来解析源数据中的日期和时间值。DATEFORMAT 和 TIMEFORMAT 是格式化字符串，必须与源数据的日期和时间值的格式相匹配。例如，加载具有日期值 `Jan-01-1999` 的源数据的 COPY 命令必须包括以下 DATEFORMAT 字符串：

```
COPY ...
            DATEFORMAT AS 'MON-DD-YYYY'
```

有关管理 COPY 数据转换的更多信息，请参阅[数据转换参数](https://docs.aws.amazon.com/redshift/latest/dg/copy-parameters-data-conversion.html)。

DATEFORMAT 和 TIMEFORMAT 字符串可包含日期时间分隔符（例如‘`-`’、‘`/`’或‘`:`’）以及下表中的日期部分和时间部分格式。

**注意**  
如果您无法将日期或时间值的格式与以下日期部分和时间部分相匹配，或如果您的日期和时间值使用的格式彼此不同，则请将 `'auto'` 参数与 DATEFORMAT 或 TIMEFORMAT 参数结合使用。在使用 DATEFORMAT 或 TIMEFORMAT 字符串时，`'auto'` 参数会识别几种不受支持的格式。有关更多信息，请参阅 [在 DATEFORMAT 和 TIMEFORMAT 中使用自动识别](automatic-recognition.md)。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_DATEFORMAT_and_TIMEFORMAT_strings.html)

默认格式日期是 YYYY-MM-DD。不带时区 (TIMESTAMP) 的默认时间戳格式是 YYYY-MM-DD HH:MI:SS。带时区 (TIMESTAMPTZ) 的默认时间戳格式是 YYYY-MM-DD HH:MI:SSOF，其中 OF 是与 UTC 的偏移两个（例如，-8:00）。您不能在 timeformat\$1string 中包含时区标识符（TZ、tz 或 OF）。秒 (SS) 字段还支持小数秒到微秒级别的细节。要加载格式与默认格式不同的 TIMESTAMPTZ 数据，请指定“自动”。

以下是您在源数据中会遇到的一些示例日期或时间，以及相应的 DATEFORMAT 或 TIMEFORMAT 字符串。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_DATEFORMAT_and_TIMEFORMAT_strings.html)

## 示例
<a name="r_DATEFORMAT_and_TIMEFORMAT_strings-examples"></a>

有关使用 TIMEFORMAT 的示例，请参阅[加载时间戳或日期戳](r_COPY_command_examples.md#r_COPY_command_examples-load-a-time-datestamp)。

# 在 DATEFORMAT 和 TIMEFORMAT 中使用自动识别
<a name="automatic-recognition"></a>

如果您指定 `'auto'` 作为 DATEFORMAT 或 TIMEFORMAT 参数的参数，Amazon Redshift 将自动识别并转换源数据中的日期格式或时间格式。下面是一个示例。

```
copy favoritemovies from 'dynamodb://ProductCatalog' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
dateformat 'auto';
```

在与 DATEFORMAT 和 TIMEFORMAT 的 `'auto'` 参数一起使用时，COPY 将识别并转换在 [DATEFORMAT 和 TIMEFORMAT 字符串示例](r_DATEFORMAT_and_TIMEFORMAT_strings.md) 中的表中列出的日期和时间格式。此外，`'auto'` 参数将识别下列在使用 DATEFORMAT 和 TIMEFORMAT 字符串时不受支持的格式。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/automatic-recognition.html)

自动识别不支持 epochsec 和 epochmillisec。

要测试是否将自动转换日期或时间戳值，请使用 CAST 函数尝试将字符串转换为日期或时间戳值。例如，下列命令测试时间戳值 `'J2345678 04:05:06.789'`：

```
create table formattest (test char(21));
insert into formattest values('J2345678 04:05:06.789');
select test, cast(test as timestamp) as timestamp, cast(test as date) as date from formattest;

        test          |      timestamp      |	date
----------------------+---------------------+------------
J2345678 04:05:06.789   1710-02-23 04:05:06	1710-02-23
```

如果 DATE 列的源数据包含时间信息，则将截断时间部分。如果 TIMESTAMP 列的源数据省略时间信息，则将使用 00:00:00 作为时间部分。

# COPY 示例
<a name="r_COPY_command_examples"></a>

**注意**  
为便于阅读，这些示例包含换行符。请不要在您的 *credentials-args* 字符串中包含换行符或空格。

**Topics**
+ [从 DynamoDB 表中加载 FAVORITEMOVIES](#r_COPY_command_examples-load-favoritemovies-from-an-amazon-dynamodb-table)
+ [从 Amazon S3 桶中加载 LISTING](#r_COPY_command_examples-load-listing-from-an-amazon-s3-bucket)
+ [从 Amazon EMR 集群中加载 LISTING](#copy-command-examples-emr)
+ [Example: COPY from Amazon S3 using a manifest](#copy-command-examples-manifest)
+ [从以竖线（默认分隔符）分隔的文件中加载 LISTING](#r_COPY_command_examples-load-listing-from-a-pipe-delimited-file-default-delimiter)
+ [使用 Parquet 格式的列式数据加载 LISTING](#r_COPY_command_examples-load-listing-from-parquet)
+ [使用 ORC 格式的列式数据加载 LISTING](#r_COPY_command_examples-load-listing-from-orc)
+ [使用选项加载 EVENT](#r_COPY_command_examples-load-event-with-options)
+ [从固定宽度的数据文件中加载 VENUE](#r_COPY_command_examples-load-venue-from-a-fixed-width-data-file)
+ [从 CSV 文件中加载 CATEGORY](#load-from-csv)
+ [加载具有显式的 IDENTITY 列值的 VENUE](#r_COPY_command_examples-load-venue-with-explicit-values-for-an-identity-column)
+ [从以竖线分隔的 GZIP 文件中加载 TIME](#r_COPY_command_examples-load-time-from-a-pipe-delimited-gzip-file)
+ [加载时间戳或日期戳](#r_COPY_command_examples-load-a-time-datestamp)
+ [从具有默认值的文件中加载数据](#r_COPY_command_examples-load-data-from-a-file-with-default-values)
+ [使用 ESCAPE 选项复制数据](#r_COPY_command_examples-copy-data-with-the-escape-option)
+ [从 JSON 中复制的示例](#r_COPY_command_examples-copy-from-json)
+ [从 Avro 中复制的示例](#r_COPY_command_examples-copy-from-avro)
+ [使用 ESCAPE 选项为 COPY 准备文件](#r_COPY_preparing_data)
+ [将 shapefile 加载到 Amazon Redshift](#copy-example-spatial-copy-shapefile)
+ [带有 NOLOAD 选项的 COPY 命令](#r_COPY_command_examples-load-noload-option)
+ [带有多字节分隔符和 ENCODING 选项的 COPY 命令](#r_COPY_command_examples-load-encoding-multibyte-delimiter-option)

## 从 DynamoDB 表中加载 FAVORITEMOVIES
<a name="r_COPY_command_examples-load-favoritemovies-from-an-amazon-dynamodb-table"></a>

AWS 开发工具包包括一个创建名为 *Movies* 的 DynamoDB 表的简单示例。（有关此示例，请参阅 [DynamoDB 入门](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.html)。） 以下示例加载包含 DynamoDB 表中数据的 Amazon Redshift MOVIES 表。Amazon Redshift 表必须已存在于数据库中。

```
copy favoritemovies from 'dynamodb://Movies'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole' 
readratio 50;
```

## 从 Amazon S3 桶中加载 LISTING
<a name="r_COPY_command_examples-load-listing-from-an-amazon-s3-bucket"></a>

以下示例从 Amazon S3 桶加载 LISTING。COPY 命令将加载 `/data/listing/` 文件夹中的所有文件。

```
copy listing
from 's3://amzn-s3-demo-bucket/data/listing/' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

## 从 Amazon EMR 集群中加载 LISTING
<a name="copy-command-examples-emr"></a>

以下示例从 Amazon EMR 集群的 lzop 压缩文件加载使用制表符分隔数据的 SALES 表。COPY 加载 `myoutput/` 文件夹中每个以 `part-` 开头的文件。

```
copy sales
from 'emr://j-SAMPLE2B500FC/myoutput/part-*' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
delimiter '\t' lzop;
```

以下示例将加载包含 Amazon EMR 集群中的 JSON 格式的数据的 SALES 表。COPY 加载 `myoutput/json/` 文件夹中的每个文件。

```
copy sales
from 'emr://j-SAMPLE2B500FC/myoutput/json/' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
JSON 's3://amzn-s3-demo-bucket/jsonpaths.txt';
```

## 使用清单指定数据文件
<a name="copy-command-examples-manifest"></a>

您可以使用清单确保 COPY 命令将从 Amazon S3 加载所有必需的文件，而且仅加载必需的文件。当您需要从不同的桶加载多个文件或加载未共享相同前缀的文件时，您也可使用清单。

例如，假设您需要加载下列三个文件：`custdata1.txt`、`custdata2.txt` 和 `custdata3.txt`。您可使用以下命令通过指定前缀来加载 `amzn-s3-demo-bucket` 中以 `custdata` 开头的所有文件：

```
copy category
from 's3://amzn-s3-demo-bucket/custdata' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

如果由于错误仅存在两个文件，则 COPY 仅加载这两个文件并成功完成，从而导致不完整的数据加载。如果桶还包含恰巧使用相同前缀的不需要的文件（例如名为 `custdata.backup` 的文件），则 COPY 还加载此文件，从而导致加载不需要的数据。

为了确保加载所有必需的文件并防止加载不需要的文件，您可使用清单文件。清单是 JSON 格式的文本文件，其中列出了要通过 COPY 命令处理的文件。例如，以下清单将加载上例中的三个文件。

```
{  
   "entries":[  
      {  
         "url":"s3://amzn-s3-demo-bucket/custdata.1",
         "mandatory":true
      },
      {  
         "url":"s3://amzn-s3-demo-bucket/custdata.2",
         "mandatory":true
      },
      {  
         "url":"s3://amzn-s3-demo-bucket/custdata.3",
         "mandatory":true
      }
   ]
}
```

可选的 `mandatory` 标志指示 COPY 是否应在文件不存在时终止。默认为 `false`。如果未找到任何文件，则无论 mandatory 设置如何，COPY 都会终止。在此示例中，如果未找到任何文件，COPY 将返回错误。将忽略可能会在仅指定键前缀（如 `custdata.backup`）的情况下选取的不需要的文件，因为它们不在清单上。

在从采用 ORC 或 Parquet 格式的数据文件中加载时，需要 `meta` 字段，如以下示例所示。

```
{  
   "entries":[  
      {  
         "url":"s3://amzn-s3-demo-bucket1/orc/2013-10-04-custdata",
         "mandatory":true,
         "meta":{  
            "content_length":99
         }
      },
      {  
         "url":"s3://amzn-s3-demo-bucket2/orc/2013-10-05-custdata",
         "mandatory":true,
         "meta":{  
            "content_length":99
         }
      }
   ]
}
```

以下示例使用名为 `cust.manifest` 的清单。

```
copy customer
from 's3://amzn-s3-demo-bucket/cust.manifest' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
format as orc
manifest;
```

您可以使用清单来加载不同桶或文件中未共享相同前缀的文件。以下示例显示了用于加载名称以日期戳开头的文件中的数据的 JSON。

```
{
  "entries": [
    {"url":"s3://amzn-s3-demo-bucket/2013-10-04-custdata.txt","mandatory":true},
    {"url":"s3://amzn-s3-demo-bucket/2013-10-05-custdata.txt","mandatory":true},
    {"url":"s3://amzn-s3-demo-bucket/2013-10-06-custdata.txt","mandatory":true},
    {"url":"s3://amzn-s3-demo-bucket/2013-10-07-custdata.txt","mandatory":true}
  ]
}
```

此清单可列出位于不同桶中的文件，前提是桶与集群位于同一 AWS 区域。

```
{
  "entries": [
    {"url":"s3://amzn-s3-demo-bucket1/custdata1.txt","mandatory":false},
    {"url":"s3://amzn-s3-demo-bucket2/custdata1.txt","mandatory":false},
    {"url":"s3://amzn-s3-demo-bucket2/custdata2.txt","mandatory":false}
  ]
}
```

## 从以竖线（默认分隔符）分隔的文件中加载 LISTING
<a name="r_COPY_command_examples-load-listing-from-a-pipe-delimited-file-default-delimiter"></a>

以下示例是一个非常简单的示例，其中未指定任何选项并且输入文件包含默认分隔符，即竖线字符（“\$1”）。

```
copy listing 
from 's3://amzn-s3-demo-bucket/data/listings_pipe.txt' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

## 使用 Parquet 格式的列式数据加载 LISTING
<a name="r_COPY_command_examples-load-listing-from-parquet"></a>

以下示例从 Amazon S3 上的名为 parquet 的文件夹加载数据。

```
copy listing 
from 's3://amzn-s3-demo-bucket/data/listings/parquet/' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
format as parquet;
```

## 使用 ORC 格式的列式数据加载 LISTING
<a name="r_COPY_command_examples-load-listing-from-orc"></a>

以下示例从 Amazon S3 上名为 `orc` 的文件夹加载数据。

```
copy listing 
from 's3://amzn-s3-demo-bucket/data/listings/orc/' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
format as orc;
```

## 使用选项加载 EVENT
<a name="r_COPY_command_examples-load-event-with-options"></a>

以下示例将竖线分隔的数据加载到 EVENT 表中并应用下列规则：
+ 如果使用了引号对来括起任何字符串，则会删除它们。
+ 空字符串和包含空白的字符串将作为 NULL 值加载。
+ 如果返回了 5 个以上的错误，则加载失败。
+ 时间戳值必须遵循指定的格式；例如，有效的时间戳为 `2008-09-26 05:43:12`。

```
copy event
from 's3://amzn-s3-demo-bucket/data/allevents_pipe.txt' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole' 
removequotes
emptyasnull
blanksasnull
maxerror 5
delimiter '|'
timeformat 'YYYY-MM-DD HH:MI:SS';
```

## 从固定宽度的数据文件中加载 VENUE
<a name="r_COPY_command_examples-load-venue-from-a-fixed-width-data-file"></a>

```
copy venue
from 's3://amzn-s3-demo-bucket/data/venue_fw.txt' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
fixedwidth 'venueid:3,venuename:25,venuecity:12,venuestate:2,venueseats:6';
```

上例假设数据文件与所示的样本数据是使用相同的方式设置格式的。在下面的示例中，空格充当占位符，以便所有列的宽度与规范中的规定相同：

```
1  Toyota Park              Bridgeview  IL0
2  Columbus Crew Stadium    Columbus    OH0
3  RFK Stadium              Washington  DC0
4  CommunityAmerica BallparkKansas City KS0
5  Gillette Stadium         Foxborough  MA68756
```

## 从 CSV 文件中加载 CATEGORY
<a name="load-from-csv"></a>

假设您要加载具有下表中所示值的 CATEGORY。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_COPY_command_examples.html)

以下示例显示了字段值用逗号隔开的文本文件的内容。

```
12,Shows,Musicals,Musical theatre
13,Shows,Plays,All "non-musical" theatre  
14,Shows,Opera,All opera, light, and "rock" opera
15,Concerts,Classical,All symphony, concerto, and choir concerts
```

如果您在加载文件时使用 DELIMITER 参数指定逗号分隔的输入，则 COPY 命令失败，因为一些输入字段包含逗号。您可通过使用 CSV 参数并将包含逗号的字段括在引号字符中来避免以上问题。如果用引号括起来的字符串中出现引号字符，则需要通过双引号字符来进行转义。默认引号字符为双引号，因此您需要使用一个额外的双引号对每个双引号进行转义。您的新输入文件与下面类似。

```
12,Shows,Musicals,Musical theatre
13,Shows,Plays,"All ""non-musical"" theatre"
14,Shows,Opera,"All opera, light, and ""rock"" opera"
15,Concerts,Classical,"All symphony, concerto, and choir concerts"
```

假定文件名为 `category_csv.txt`，则可通过使用以下 COPY 命令加载文件：

```
copy category
from 's3://amzn-s3-demo-bucket/data/category_csv.txt' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole' 
csv;
```

或者，若要避免对输入中的双引号进行转义，可通过使用 QUOTE AS 参数来指定其他引号字符。例如，以下版本的 `category_csv.txt` 使用“`%`”作为引号字符。

```
12,Shows,Musicals,Musical theatre
13,Shows,Plays,%All "non-musical" theatre%
14,Shows,Opera,%All opera, light, and "rock" opera%
15,Concerts,Classical,%All symphony, concerto, and choir concerts%
```

以下 COPY 命令使用 QUOTE AS 来加载 `category_csv.txt`：

```
copy category
from 's3://amzn-s3-demo-bucket/data/category_csv.txt' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole' 
csv quote as '%';
```

## 加载具有显式的 IDENTITY 列值的 VENUE
<a name="r_COPY_command_examples-load-venue-with-explicit-values-for-an-identity-column"></a>

以下示例假设在创建 VENUE 表时，至少将一个列（如 `venueid` 列）指定为 IDENTITY 列。此命令将覆盖 IDENTITY 列的自动生成值的默认 IDENTITY 行为，并将改为从 venue.txt 文件加载显式值。使用 EXLICIT\$1IDS 选项时，Amazon Redshift 不会检查表中是否加载了重复的 IDENTITY 值。

```
copy venue
from 's3://amzn-s3-demo-bucket/data/venue.txt' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
explicit_ids;
```

## 从以竖线分隔的 GZIP 文件中加载 TIME
<a name="r_COPY_command_examples-load-time-from-a-pipe-delimited-gzip-file"></a>

以下示例从用竖线分隔的 GZIP 文件加载 TIME 表：

```
copy time
from 's3://amzn-s3-demo-bucket/data/timerows.gz' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
gzip
delimiter '|';
```

## 加载时间戳或日期戳
<a name="r_COPY_command_examples-load-a-time-datestamp"></a>

以下示例加载具有带格式的时间戳的数据。

**注意**  
`HH:MI:SS` 的 TIMEFORMAT 还可支持超出 `SS` 的高达微秒细节级别的小数秒。此示例中使用的文件 `time.txt` 包含一行，即 `2009-01-12 14:15:57.119568`。

```
copy timestamp1 
from 's3://amzn-s3-demo-bucket/data/time.txt' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
timeformat 'YYYY-MM-DD HH:MI:SS';
```

此复制的结果如下所示：

```
select * from timestamp1;
c1
----------------------------
2009-01-12 14:15:57.119568
(1 row)
```

## 从具有默认值的文件中加载数据
<a name="r_COPY_command_examples-load-data-from-a-file-with-default-values"></a>

以下示例使用 TICKIT 数据库中的 VENUE 表的变体。考虑使用以下语句定义的 VENUE\$1NEW 表：

```
create table venue_new(
venueid smallint not null,
venuename varchar(100) not null,
venuecity varchar(30),
venuestate char(2),
venueseats integer not null default '1000');
```

考虑未包含任何 VENUESEATS 列值的 venue\$1noseats.txt 数据文件，如以下示例中所示：

```
1|Toyota Park|Bridgeview|IL|
2|Columbus Crew Stadium|Columbus|OH|
3|RFK Stadium|Washington|DC|
4|CommunityAmerica Ballpark|Kansas City|KS|
5|Gillette Stadium|Foxborough|MA|
6|New York Giants Stadium|East Rutherford|NJ|
7|BMO Field|Toronto|ON|
8|The Home Depot Center|Carson|CA|
9|Dick's Sporting Goods Park|Commerce City|CO|
10|Pizza Hut Park|Frisco|TX|
```

以下 COPY 语句将成功地从此文件中加载表并对已省略的列应用 DEFAULT 值（“1000”）：

```
copy venue_new(venueid, venuename, venuecity, venuestate) 
from 's3://amzn-s3-demo-bucket/data/venue_noseats.txt' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
delimiter '|';
```

现在查看加载的表：

```
select * from venue_new order by venueid;
venueid |         venuename          |    venuecity    | venuestate | venueseats
---------+----------------------------+-----------------+------------+------------
1 | Toyota Park                | Bridgeview      | IL         |       1000
2 | Columbus Crew Stadium      | Columbus        | OH         |       1000
3 | RFK Stadium                | Washington      | DC         |       1000
4 | CommunityAmerica Ballpark  | Kansas City     | KS         |       1000
5 | Gillette Stadium           | Foxborough      | MA         |       1000
6 | New York Giants Stadium    | East Rutherford | NJ         |       1000
7 | BMO Field                  | Toronto         | ON         |       1000
8 | The Home Depot Center      | Carson          | CA         |       1000
9 | Dick's Sporting Goods Park | Commerce City   | CO         |       1000
10 | Pizza Hut Park             | Frisco          | TX         |       1000
(10 rows)
```

在以下示例中，除了假设此文件中未包含任何 VENUESEATS 数据之外，还假设未包含任何 VENUENAME 数据：

```
1||Bridgeview|IL|
2||Columbus|OH|
3||Washington|DC|
4||Kansas City|KS|
5||Foxborough|MA|
6||East Rutherford|NJ|
7||Toronto|ON|
8||Carson|CA|
9||Commerce City|CO|
10||Frisco|TX|
```

 通过使用相同的表定义，以下 COPY 语句失败，因为未为 VENUENAME 指定任何 DEFAULT 值，并且 VENUENAME 是一个非 NULL 列：

```
copy venue(venueid, venuecity, venuestate) 
from 's3://amzn-s3-demo-bucket/data/venue_pipe.txt' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
delimiter '|';
```

现在考虑使用 IDENTITY 列的 VENUE 表的变体：

```
create table venue_identity(
venueid int identity(1,1),
venuename varchar(100) not null,
venuecity varchar(30),
venuestate char(2),
venueseats integer not null default '1000');
```

与上例一样，假设 VENUESEATS 列没有源文件中的对应值。以下 COPY 语句成功地加载表（包括预先定义的 IDENTITY 数据值）而不是自动生成这些值：

```
copy venue(venueid, venuename, venuecity, venuestate) 
from 's3://amzn-s3-demo-bucket/data/venue_pipe.txt' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
delimiter '|' explicit_ids;
```

此语句将失败，因为它未包含 IDENTITY 列（列列表中缺少 VENUEID），而是包含 EXPLICIT\$1IDS 参数：

```
copy venue(venuename, venuecity, venuestate) 
from 's3://amzn-s3-demo-bucket/data/venue_pipe.txt' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
delimiter '|' explicit_ids;
```

此语句将失败，因为它不包含 EXPLICIT\$1IDS 参数：

```
copy venue(venueid, venuename, venuecity, venuestate)
from 's3://amzn-s3-demo-bucket/data/venue_pipe.txt' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
delimiter '|';
```

## 使用 ESCAPE 选项复制数据
<a name="r_COPY_command_examples-copy-data-with-the-escape-option"></a>

以下示例演示如何加载与分隔符字符（在此示例中为竖线字符）匹配的字符。在输入文件中，确保使用反斜杠字符 (\$1) 转义您要加载的所有竖线字符 (\$1)。然后使用 ESCAPE 参数加载此文件。

```
$ more redshiftinfo.txt
1|public\|event\|dwuser
2|public\|sales\|dwuser

create table redshiftinfo(infoid int,tableinfo varchar(50));

copy redshiftinfo from 's3://amzn-s3-demo-bucket/data/redshiftinfo.txt' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole' 
delimiter '|' escape;

select * from redshiftinfo order by 1;
infoid |       tableinfo
-------+--------------------
1      | public|event|dwuser
2      | public|sales|dwuser
(2 rows)
```

如果没有 ESCAPE 参数，此 COPY 命令将失败，并返回 `Extra column(s) found` 错误。

**重要**  
如果使用包含 ESCAPE 参数的 COPY 加载数据，则还必须在 UNLOAD 命令中指定 ESCAPE 参数与以生成反向输出文件。同样，如果您使用 ESCAPE 参数执行 UNLOAD 命令，则在您对相同数据执行 COPY 操作时需要使用 ESCAPE 参数。

## 从 JSON 中复制的示例
<a name="r_COPY_command_examples-copy-from-json"></a>

在以下示例中，您加载具有以下数据的 CATEGORY 表。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_COPY_command_examples.html)

**Topics**
+ [使用“auto”选项从 JSON 数据中加载](#copy-from-json-examples-using-auto)
+ [使用“auto ignorecase”选项从 JSON 数据中加载](#copy-from-json-examples-using-auto-ignorecase)
+ [使用 JSONPaths 文件从 JSON 数据中加载](#copy-from-json-examples-using-jsonpaths)
+ [使用 JSONPaths 文件从 JSON 数组中加载](#copy-from-json-examples-using-jsonpaths-arrays)

### 使用“auto”选项从 JSON 数据中加载
<a name="copy-from-json-examples-using-auto"></a>

要使用 `'auto'` 选项从 JSON 数据加载，JSON 数据必须包含一组对象。键名称必须与列名称匹配，但顺序并不重要。下面显示了名为 `category_object_auto.json` 的文件的内容。

```
{
    "catdesc": "Major League Baseball",
    "catid": 1,
    "catgroup": "Sports",
    "catname": "MLB"
}
{
    "catgroup": "Sports",
    "catid": 2,
    "catname": "NHL",
    "catdesc": "National Hockey League"
}
{
    "catid": 3,
    "catname": "NFL",
    "catgroup": "Sports",
    "catdesc": "National Football League"
}
{
    "bogus": "Bogus Sports LLC",
    "catid": 4,
    "catgroup": "Sports",
    "catname": "NBA",
    "catdesc": "National Basketball Association"
}
{
    "catid": 5,
    "catgroup": "Shows",
    "catname": "Musicals",
    "catdesc": "All symphony, concerto, and choir concerts"
}
```

若要从上例中的 JSON 数据文件加载，请执行以下 COPY 命令。

```
copy category
from 's3://amzn-s3-demo-bucket/category_object_auto.json'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole' 
json 'auto';
```

### 使用“auto ignorecase”选项从 JSON 数据中加载
<a name="copy-from-json-examples-using-auto-ignorecase"></a>

要使用 `'auto ignorecase'` 选项从 JSON 数据加载，JSON 数据必须包含一组对象。键名称的大小写不必与列名称匹配，顺序并不重要。下面显示了名为 `category_object_auto-ignorecase.json` 的文件的内容。

```
{
    "CatDesc": "Major League Baseball",
    "CatID": 1,
    "CatGroup": "Sports",
    "CatName": "MLB"
}
{
    "CatGroup": "Sports",
    "CatID": 2,
    "CatName": "NHL",
    "CatDesc": "National Hockey League"
}
{
    "CatID": 3,
    "CatName": "NFL",
    "CatGroup": "Sports",
    "CatDesc": "National Football League"
}
{
    "bogus": "Bogus Sports LLC",
    "CatID": 4,
    "CatGroup": "Sports",
    "CatName": "NBA",
    "CatDesc": "National Basketball Association"
}
{
    "CatID": 5,
    "CatGroup": "Shows",
    "CatName": "Musicals",
    "CatDesc": "All symphony, concerto, and choir concerts"
}
```

若要从上例中的 JSON 数据文件加载，请执行以下 COPY 命令。

```
copy category
from 's3://amzn-s3-demo-bucket/category_object_auto ignorecase.json'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole' 
json 'auto ignorecase';
```

### 使用 JSONPaths 文件从 JSON 数据中加载
<a name="copy-from-json-examples-using-jsonpaths"></a>

如果 JSON 数据对象未直接对应于列名称，则可使用 JSONPaths 文件将 JSON 元素映射到列。顺序在 JSON 源数据中也不重要，但 JSONPaths 文件表达式的顺序必须与列顺序匹配。假设您具有以下名为 `category_object_paths.json` 的数据文件。

```
{
    "one": 1,
    "two": "Sports",
    "three": "MLB",
    "four": "Major League Baseball"
}
{
    "three": "NHL",
    "four": "National Hockey League",
    "one": 2,
    "two": "Sports"
}
{
    "two": "Sports",
    "three": "NFL",
    "one": 3,
    "four": "National Football League"
}
{
    "one": 4,
    "two": "Sports",
    "three": "NBA",
    "four": "National Basketball Association"
}
{
    "one": 6,
    "two": "Shows",
    "three": "Musicals",
    "four": "All symphony, concerto, and choir concerts"
}
```

以下名为 `category_jsonpath.json` 的 JSONPaths 文件会将源数据映射到表列。

```
{
    "jsonpaths": [
        "$['one']",
        "$['two']",
        "$['three']",
        "$['four']"
    ]
}
```

若要从上例中的 JSON 数据文件加载，请执行以下 COPY 命令。

```
copy category
from 's3://amzn-s3-demo-bucket/category_object_paths.json'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole' 
json 's3://amzn-s3-demo-bucket/category_jsonpath.json';
```

### 使用 JSONPaths 文件从 JSON 数组中加载
<a name="copy-from-json-examples-using-jsonpaths-arrays"></a>

若要从包含一组数组的 JSON 数据加载，必须使用 JSONPaths 文件将数组元素映射到列。假设您具有以下名为 `category_array_data.json` 的数据文件。

```
[1,"Sports","MLB","Major League Baseball"]
[2,"Sports","NHL","National Hockey League"]
[3,"Sports","NFL","National Football League"]
[4,"Sports","NBA","National Basketball Association"]
[5,"Concerts","Classical","All symphony, concerto, and choir concerts"]
```

以下名为 `category_array_jsonpath.json` 的 JSONPaths 文件会将源数据映射到表列。

```
{
    "jsonpaths": [
        "$[0]",
        "$[1]",
        "$[2]",
        "$[3]"
    ]
}
```

若要从上例中的 JSON 数据文件加载，请执行以下 COPY 命令。

```
copy category
from 's3://amzn-s3-demo-bucket/category_array_data.json'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole' 
json 's3://amzn-s3-demo-bucket/category_array_jsonpath.json';
```

## 从 Avro 中复制的示例
<a name="r_COPY_command_examples-copy-from-avro"></a>

在以下示例中，您加载具有以下数据的 CATEGORY 表。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_COPY_command_examples.html)

**Topics**
+ [使用“auto”选项从 Avro 数据中加载](#copy-from-avro-examples-using-auto)
+ [使用“auto ignorecase”选项从 Avro 数据中加载](#copy-from-avro-examples-using-auto-ignorecase)
+ [使用 JSONPaths 文件从 Avro 数据中加载](#copy-from-avro-examples-using-avropaths)

### 使用“auto”选项从 Avro 数据中加载
<a name="copy-from-avro-examples-using-auto"></a>

若要使用 `'auto'` 参数从 Avro 数据加载，Avro schema 中的字段名称必须与列名称匹配。在使用 `'auto'` 参数时，顺序并不重要。下面显示了名为 `category_auto.avro` 的文件的 schema。

```
{
    "name": "category",
    "type": "record",
    "fields": [
        {"name": "catid", "type": "int"},
        {"name": "catdesc", "type": "string"},
        {"name": "catname", "type": "string"},
        {"name": "catgroup", "type": "string"},
}
```

Avro 文件中的数据为二进制格式，不是人类可读的格式。下面显示了 `category_auto.avro` 文件中的数据的 JSON 表示形式。

```
{
   "catid": 1,
   "catdesc": "Major League Baseball",
   "catname": "MLB",
   "catgroup": "Sports"
}
{
   "catid": 2,
   "catdesc": "National Hockey League",
   "catname": "NHL",
   "catgroup": "Sports"
}
{
   "catid": 3,
   "catdesc": "National Basketball Association",
   "catname": "NBA",
   "catgroup": "Sports"
}
{
   "catid": 4,
   "catdesc": "All symphony, concerto, and choir concerts",
   "catname": "Classical",
   "catgroup": "Concerts"
}
```

要从上例中的 Avro 数据文件加载，请执行以下 COPY 命令。

```
copy category
from 's3://amzn-s3-demo-bucket/category_auto.avro'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
format as avro 'auto';
```

### 使用“auto ignorecase”选项从 Avro 数据中加载
<a name="copy-from-avro-examples-using-auto-ignorecase"></a>

若要使用 `'auto ignorecase'` 参数从 Avro 数据加载，Avro schema 中的字段名称的大小写不必与列名称的大小写匹配。在使用 `'auto ignorecase'` 参数时，顺序并不重要。下面显示了名为 `category_auto-ignorecase.avro` 的文件的 schema。

```
{
    "name": "category",
    "type": "record",
    "fields": [
        {"name": "CatID", "type": "int"},
        {"name": "CatDesc", "type": "string"},
        {"name": "CatName", "type": "string"},
        {"name": "CatGroup", "type": "string"},
}
```

Avro 文件中的数据为二进制格式，不是人类可读的格式。下面显示了 `category_auto-ignorecase.avro` 文件中的数据的 JSON 表示形式。

```
{
   "CatID": 1,
   "CatDesc": "Major League Baseball",
   "CatName": "MLB",
   "CatGroup": "Sports"
}
{
   "CatID": 2,
   "CatDesc": "National Hockey League",
   "CatName": "NHL",
   "CatGroup": "Sports"
}
{
   "CatID": 3,
   "CatDesc": "National Basketball Association",
   "CatName": "NBA",
   "CatGroup": "Sports"
}
{
   "CatID": 4,
   "CatDesc": "All symphony, concerto, and choir concerts",
   "CatName": "Classical",
   "CatGroup": "Concerts"
}
```

要从上例中的 Avro 数据文件加载，请执行以下 COPY 命令。

```
copy category
from 's3://amzn-s3-demo-bucket/category_auto-ignorecase.avro'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
format as avro 'auto ignorecase';
```

### 使用 JSONPaths 文件从 Avro 数据中加载
<a name="copy-from-avro-examples-using-avropaths"></a>

如果 Avro schema 中的字段名称未直接对应于列名称，则可使用 JSONPaths 文件将 schema 元素映射到列。JSONPaths 文件表达式的顺序必须与列顺序一致。

假设您具有名为 `category_paths.avro` 的数据文件，其中包含的数据与上例相同，但具有以下架构。

```
{
    "name": "category",
    "type": "record",
    "fields": [
        {"name": "id", "type": "int"},
        {"name": "desc", "type": "string"},
        {"name": "name", "type": "string"},
        {"name": "group", "type": "string"},
        {"name": "region", "type": "string"} 
     ]
}
```

以下名为 `category_path.avropath` 的 JSONPaths 文件会将源数据映射到表列。

```
{
    "jsonpaths": [
        "$['id']",
        "$['group']",
        "$['name']",
        "$['desc']"
    ]
}
```

要从上例中的 Avro 数据文件加载，请执行以下 COPY 命令。

```
copy category
from 's3://amzn-s3-demo-bucket/category_object_paths.avro'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole' 
format avro 's3://amzn-s3-demo-bucket/category_path.avropath ';
```

## 使用 ESCAPE 选项为 COPY 准备文件
<a name="r_COPY_preparing_data"></a>

以下示例描述了在使用包含 ESCAPE 参数的 COPY 命令将数据导入到 Amazon Redshift 表中之前，如何准备数据以“转义”换行符。如果未准备数据以限定换行符，则 Amazon Redshift 将会在您运行 COPY 命令时返回加载错误，因为换行符一般用作记录分隔符。

例如，考虑要复制到 Amazon Redshift 表中的一个文件或外部表中的一个列。如果该文件或列包含 XML 格式的内容或类似数据，则需要确保使用反斜杠字符 (\$1) 转义此内容中的所有换行符 (\$1n)。

包含嵌入换行符的文件或表提供了相对轻松的匹配模式。每个嵌入的换行符很有可能始终跟随一个 `>` 字符（在这二者之间可能还包含一些空格字符（`' '` 或制表符）），如下面的名为 `nlTest1.txt` 的文本文件的示例中所示。

```
$ cat nlTest1.txt
<xml start>
<newline characters provide>
<line breaks at the end of each>
<line in content>
</xml>|1000
<xml>
</xml>|2000
```

在以下示例中，您可运行文本处理实用工具预先处理源文件，并在需要的位置插入转义字符。（`|` 字符旨在用作分隔符，以便在列数据复制到 Amazon Redshift 表中后分隔这些数据。） 

```
$ sed -e ':a;N;$!ba;s/>[[:space:]]*\n/>\\\n/g' nlTest1.txt > nlTest2.txt
```

同样，可使用 Perl 执行类似操作：

```
cat nlTest1.txt | perl -p -e 's/>\s*\n/>\\\n/g' > nlTest2.txt
```

为了便于将 `nlTest2.txt` 文件中的数据加载到 Amazon Redshift 中，我们在 Amazon Redshift 中创建了一个包含两列的表。第一列 c1 是字符列，用于放置 `nlTest2.txt` 文件中 XML 格式的内容。第二列 c2 将放置从同一文件加载的整数值。

在运行 `sed` 命令后，可使用 ESCAPE 参数将 `nlTest2.txt` 文件中的数据正确地加载到 Amazon Redshift 表中。

**注意**  
如果您在 COPY 命令中包含 ESCAPE 参数，则它会将一些包含反斜杠字符的特殊字符（包括换行符）进行转义。

```
copy t2 from 's3://amzn-s3-demo-bucket/data/nlTest2.txt' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'  
escape
delimiter as '|';

select * from t2 order by 2;

c1           |  c2
-------------+------
<xml start>
<newline characters provide>
<line breaks at the end of each>
<line in content>
</xml>
| 1000
<xml>
</xml>       | 2000
(2 rows)
```

您可以类似方式准备从外部数据库导出的数据文件。例如，对于 Oracle 数据库，可对要复制到 Amazon Redshift 中的表中的每个受影响的列使用 REPLACE 函数。

```
SELECT c1, REPLACE(c2, \n',\\n' ) as c2 from my_table_with_xml
```

此外，许多用于定期处理大量数据的数据库导出和提取、转换、加载 (ETL) 工具提供了指定转义字符和分隔符字符的选项。

## 将 shapefile 加载到 Amazon Redshift
<a name="copy-example-spatial-copy-shapefile"></a>

以下示例演示如何使用 COPY 加载 Esri shapefile。有关加载 shapefile 的更多信息，请参阅[将 shapefile 加载到 Amazon Redshift](spatial-copy-shapefile.md)。

### 加载一个 shapefile
<a name="copy-example-spatial-copy-shapefile-loading-copy"></a>

以下步骤介绍如何使用 COPY 命令从 Amazon S3 中摄取 OpenStreetMap 数据。此示例假定 [Geofabrik 下载站点的](https://download.geofabrik.de/europe.html) Norway shapefile 归档已经上载到 AWS 区域中的私有 Amazon S3 桶。`.shp`、`.shx` 和 `.dbf` 文件必须共享相同的 Amazon S3 前缀和文件名。

#### 无需简化即可摄取数据
<a name="spatial-copy-shapefile-loading-copy-fits"></a>

以下命令可创建表并摄取可适合最大几何大小的数据，而无需进行任何简化。在您的首选 GIS 软件中打开 `gis_osm_natural_free_1.shp`，然后检查此图层中的列。预设情况下，IDENTITY 或 GEOMETRY 列位于首位。当 GEOMETRY 列位于首位时，您可以创建表，如下所示。

```
CREATE TABLE norway_natural (
   wkb_geometry GEOMETRY,
   osm_id BIGINT,
   code INT,
   fclass VARCHAR,
   name VARCHAR);
```

或者，当 IDENTITY 列位于首位时，您可以创建表，如下所示。

```
CREATE TABLE norway_natural_with_id (
   fid INT IDENTITY(1,1),
   wkb_geometry GEOMETRY,
   osm_id BIGINT,
   code INT,
   fclass VARCHAR,
   name VARCHAR);
```

现在，您可以使用 COPY 摄取数据。

```
COPY norway_natural FROM 's3://bucket_name/shapefiles/norway/gis_osm_natural_free_1.shp'
FORMAT SHAPEFILE
CREDENTIALS 'aws_iam_role=arn:aws:iam::123456789012:role/MyRoleName';
INFO: Load into table 'norway_natural' completed, 83891 record(s) loaded successfully
```

或者，您可以按如下所示摄取数据。

```
COPY norway_natural_with_id FROM 's3://bucket_name/shapefiles/norway/gis_osm_natural_free_1.shp'
FORMAT SHAPEFILE
CREDENTIALS 'aws_iam_role=arn:aws:iam::123456789012:role/MyRoleName';
INFO: Load into table 'norway_natural_with_id' completed, 83891 record(s) loaded successfully.
```

#### 通过简化摄取数据
<a name="spatial-copy-shapefile-loading-copy-no-fit"></a>

以下命令创建一个表，并尝试在不进行任何简化的情况下摄取无法适合最大几何大小的数据。检查 `gis_osm_water_a_free_1.shp` shapefile 并创建相应的表，如下所示。

```
CREATE TABLE norway_water (
   wkb_geometry GEOMETRY,
   osm_id BIGINT,
   code INT,
   fclass VARCHAR,
   name VARCHAR);
```

当 COPY 命令运行时，会导致错误。

```
COPY norway_water FROM 's3://bucket_name/shapefiles/norway/gis_osm_water_a_free_1.shp'
FORMAT SHAPEFILE
CREDENTIALS 'aws_iam_role=arn:aws:iam::123456789012:role/MyRoleName';
ERROR:  Load into table 'norway_water' failed.  Check 'stl_load_errors' system table for details.
```

查询 `STL_LOAD_ERRORS` 显示几何体过大。

```
SELECT line_number, btrim(colname), btrim(err_reason) FROM stl_load_errors WHERE query = pg_last_copy_id();
 line_number |    btrim     |                                 btrim
-------------+--------------+-----------------------------------------------------------------------
     1184705 | wkb_geometry | Geometry size: 1513736 is larger than maximum supported size: 1048447
```

为了克服这个问题，将 `SIMPLIFY AUTO` 参数添加到 COPY 命令中以简化几何体。

```
COPY norway_water FROM 's3://bucket_name/shapefiles/norway/gis_osm_water_a_free_1.shp'
FORMAT SHAPEFILE
SIMPLIFY AUTO
CREDENTIALS 'aws_iam_role=arn:aws:iam::123456789012:role/MyRoleName';

INFO:  Load into table 'norway_water' completed, 1989196 record(s) loaded successfully.
```

要查看简化的行和几何体，请查询 `SVL_SPATIAL_SIMPLIFY`。

```
SELECT * FROM svl_spatial_simplify WHERE query = pg_last_copy_id();
 query | line_number | maximum_tolerance | initial_size | simplified | final_size |   final_tolerance
-------+-------------+-------------------+--------------+------------+------------+----------------------
    20 |     1184704 |                -1 |      1513736 | t          |    1008808 |   1.276386653895e-05
    20 |     1664115 |                -1 |      1233456 | t          |    1023584 | 6.11707814796635e-06
```

使用容差低于自动计算容差的 SIMPLIFY AUTO *max\$1tolerance* 可能会导致摄入误差。在这种情况下，请使用 MAXERROR 忽略错误。

```
COPY norway_water FROM 's3://bucket_name/shapefiles/norway/gis_osm_water_a_free_1.shp'
FORMAT SHAPEFILE
SIMPLIFY AUTO 1.1E-05
MAXERROR 2
CREDENTIALS 'aws_iam_role=arn:aws:iam::123456789012:role/MyRoleName';

INFO:  Load into table 'norway_water' completed, 1989195 record(s) loaded successfully.
INFO:  Load into table 'norway_water' completed, 1 record(s) could not be loaded.  Check 'stl_load_errors' system table for details.
```

再次查询 `SVL_SPATIAL_SIMPLIFY` 来识别 COPY 未成功加载的记录。

```
SELECT * FROM svl_spatial_simplify WHERE query = pg_last_copy_id();
 query | line_number | maximum_tolerance | initial_size | simplified | final_size | final_tolerance
-------+-------------+-------------------+--------------+------------+------------+-----------------
    29 |     1184704 |           1.1e-05 |      1513736 | f          |          0 |               0
    29 |     1664115 |           1.1e-05 |      1233456 | t          |     794432 |         1.1e-05
```

在这个示例中，第一条记录没有成功适应，因此 `simplified` 列显示为 false。第二条记录已在给定容差范围内加载。但是，最终大小比使用自动计算的容差大，而不指定最大公差。

### 正在从压缩的 shapefile 文件加载
<a name="copy-example-spatial-copy-shapefile-compressed"></a>

Amazon Redshift COPY 支持从压缩的 shapefile 中摄取数据。所有 shapefile 组件必须具有相同的 Amazon S3 前缀和相同的压缩后缀。例如，假设您要加载上面示例中的数据。在本例中，文件 `gis_osm_water_a_free_1.shp.gz`、`gis_osm_water_a_free_1.dbf.gz` 和 `gis_osm_water_a_free_1.shx.gz` 必须共享相同的 Amazon S3 目录。COPY 命令需要 GZIP 选项，FROM 子句必须指定正确的压缩文件，如下所示。

```
COPY norway_natural FROM 's3://bucket_name/shapefiles/norway/compressed/gis_osm_natural_free_1.shp.gz'
FORMAT SHAPEFILE
GZIP
CREDENTIALS 'aws_iam_role=arn:aws:iam::123456789012:role/MyRoleName';
INFO:  Load into table 'norway_natural' completed, 83891 record(s) loaded successfully.
```

### 正在将数据加载到具有不同列顺序的表
<a name="copy-example-spatial-copy-shapefile-column-order"></a>

如果您有一个没有将 `GEOMETRY` 作为第一列的表，则可以使用列映射将列映射到目标表。例如，创建一个将 `osm_id` 指定为第一列的表。

```
CREATE TABLE norway_natural_order (
   osm_id BIGINT,
   wkb_geometry GEOMETRY,
   code INT,
   fclass VARCHAR,
   name VARCHAR);
```

然后使用列映射摄取 shapefile。

```
COPY norway_natural_order(wkb_geometry, osm_id, code, fclass, name) 
FROM 's3://bucket_name/shapefiles/norway/gis_osm_natural_free_1.shp'
FORMAT SHAPEFILE
CREDENTIALS 'aws_iam_role=arn:aws:iam::123456789012:role/MyRoleName';
INFO:  Load into table 'norway_natural_order' completed, 83891 record(s) loaded successfully.
```

### 将数据加载到具有 geography 列的表中
<a name="copy-example-spatial-copy-shapefile-geography"></a>

如果某个表具有 `GEOGRAPHY` 列，请首先提取到 `GEOMETRY` 列，然后将对象强制转换为 `GEOGRAPHY` 对象。例如，在将 shapefile 复制到 `GEOMETRY` 列后，对表进行更改，添加 `GEOGRAPHY` 数据类型。

```
ALTER TABLE norway_natural ADD COLUMN wkb_geography GEOGRAPHY;
```

然后将 geometry 转换为 geography。

```
UPDATE norway_natural SET wkb_geography = wkb_geometry::geography;
```

（可选）您可以删除 `GEOMETRY` 列。

```
ALTER TABLE norway_natural DROP COLUMN wkb_geometry;
```

## 带有 NOLOAD 选项的 COPY 命令
<a name="r_COPY_command_examples-load-noload-option"></a>

要在实际加载数据之前验证数据文件，请使用带有 NOLOAD 选项的 COPY 命令。Amazon Redshift 会解析输入文件并显示发生的任何错误。以下示例使用 NOLOAD 选项，实际上并未将任何行加载到表中。

```
COPY public.zipcode1
FROM 's3://amzn-s3-demo-bucket/mydata/zipcode.csv' 
DELIMITER ';' 
IGNOREHEADER 1 REGION 'us-east-1'
NOLOAD
CREDENTIALS 'aws_iam_role=arn:aws:iam::123456789012:role/myRedshiftRole';

Warnings:
Load into table 'zipcode1' completed, 0 record(s) loaded successfully.
```

## 带有多字节分隔符和 ENCODING 选项的 COPY 命令
<a name="r_COPY_command_examples-load-encoding-multibyte-delimiter-option"></a>

以下示例从包含多字节数据的 Amazon S3 文件中加载 LATIN1。COPY 命令以八进制形式 `\302\246\303\254` 指定分隔符，来分隔编码为 ISO-8859-1 的输入文件中的字段。要以 UTF-8 形式指定相同的分隔符，请指定 `DELIMITER '¦ì'`。

```
COPY latin1
FROM 's3://amzn-s3-demo-bucket/multibyte/myfile' 
IAM_ROLE 'arn:aws:iam::123456789012:role/myRedshiftRole'
DELIMITER '\302\246\303\254'
ENCODING ISO88591
```

# CREATE DATABASE
<a name="r_CREATE_DATABASE"></a>

创建新数据库。

要创建数据库，您必须是超级用户或拥有 CREATEDB 权限。要创建与零 ETL 集成关联的数据库，您必须是超级用户或同时拥有 CREATEDB 和 CREATEUSER 权限。

您不能在以下事务块中运行 CREATE DATABASE：(BEGIN ... END)。有关事务的更多信息，请参阅 [Amazon Redshift 中的隔离级别](c_serial_isolation.md)。

## 语法
<a name="r_CREATE_DATABASE-synopsis"></a>

```
CREATE DATABASE database_name 
[ { [ 
      FROM INTEGRATION '<integration_id>'[ DATABASE '<source_database>' ]
      [ SET ]
      [ ACCEPTINVCHARS [=] { TRUE | FALSE }]
      [ QUERY_ALL_STATES [=] { TRUE | FALSE }] 
      [ REFRESH_INTERVAL <interval> ] 
      [ TRUNCATECOLUMNS [=] { TRUE | FALSE } ]
      [ HISTORY_MODE [=] {TRUE | FALSE} ]
    ]
    [ WITH ]
    [ OWNER [=] db_owner ]
    [ CONNECTION LIMIT { limit | UNLIMITED } ]
    [ COLLATE { CASE_SENSITIVE | CS | CASE_INSENSITIVE | CI } ]
    [ ISOLATION LEVEL { SNAPSHOT | SERIALIZABLE } ]
  }
  | { FROM { { ARN '<arn>' } { WITH DATA CATALOG SCHEMA '<schema>' | WITH NO DATA CATALOG SCHEMA } } }
  | { IAM_ROLE  {default | 'SESSION' | 'arn:aws:iam::<account-id>:role/<role-name>' } }
  | { [ WITH PERMISSIONS ] FROM DATASHARE datashare_name OF [ ACCOUNT account_id ] NAMESPACE namespace_guid }
]
```

## 参数
<a name="r_CREATE_DATABASE-parameters"></a>

 *database\$1name*   
新数据库的名称。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。

FROM INTEGRATION '<integration\$1id>' [ DATABASE '<source\$1database>' ]   
指定是否使用零 ETL 集成标识符创建数据库。您可以从 SVV\$1INTEGRATION 系统视图中检索 `integration_id`。对于 Aurora PostgreSQL 零 ETL 集成，还需要指定 `source_database` 名称，这也可以从 SVV\$1INTEGRATION 中检索到。  
有关示例，请参阅[创建数据库以接收零 ETL 集成的结果](#r_CREATE_DATABASE-integration)。有关使用零 ETL 集成创建数据库的更多信息，请参阅*《Amazon Redshift 管理指南》*中的[在 Amazon Redshift 中创建目标数据库](https://docs.aws.amazon.com/redshift/latest/mgmt/zero-etl-using.creating-db.html)。

SET  
可选关键字。

ACCEPTINVCHARS [=] \$1 TRUE \$1 FALSE \$1  
ACCEPTINVCHARS 子句设置在检测到 VARCHAR 数据类型的无效字符时，零 ETL 集成表是否继续摄取。在遇到无效字符时，无效字符将被替换为默认 `?` 字符。

QUERY\$1ALL\$1STATES [=] \$1 TRUE \$1 FALSE \$1  
QUERY\$1ALL\$1STATES 子句设置是否可以在所有状态（`Synced`、`Failed`、`ResyncRequired` 和 `ResyncInitiated`）下查询零 ETL 集成表。默认情况下，只能在 `Synced` 状态下查询零 ETL 集成表。

REFRESH\$1INTERVAL <interval>  
REFRESH\$1INTERVAL 子句设置将数据从零 ETL 源刷新到目标数据库的大致时间间隔（秒）。对于源类型为 Aurora MySQL、Aurora PostgreSQL 或 RDS for MySQL 的零 ETL 集成，该值可设置为 0-432000 秒（5 天）。对于 Amazon DynamoDB 零 ETL 集成，值可设置为 900-432000 秒（15 分钟 - 5 天）。对于源类型为 Aurora MySQL、Aurora PostgreSQL 或 RDS for MySQL 的零 ETL 集成，默认 `interval` 为零（0）秒。对于 Amazon DynamoDB 零 ETL 集成，默认 `interval` 为 900 秒（15 分钟）。

TRUNCATECOLUMNS [=] \$1 TRUE \$1 FALSE \$1  
TRUNCATECOLUMNS 子句设置当 VARCHAR 列或 SUPER 列属性的值超出限制时，零 ETL 集成表是否继续摄取。当为 `TRUE` 时，值会被截断以适合该列，而溢出的 JSON 属性的值会被截断以适合 SUPER 列。

HISTORY\$1MODE [=] \$1TRUE \$1 FALSE\$1  
一个子句，用于指定 Amazon Redshift 是否为指定数据库中的所有新表设置历史记录模式。此选项仅适用于为零 ETL 集成创建的数据库。  
HISTORY\$1MODE 子句可设置为 `TRUE` 或 `FALSE`。默认值为 `FALSE`。有关 HISTORY\$1MODE 的信息，请参阅《Amazon Redshift 管理指南》**中的[历史记录模式](https://docs.aws.amazon.com/redshift/latest/mgmt/zero-etl-history-mode.html)。

WITH  
可选关键字。

OWNER [=] db\$1owner  
指定数据库所有者的用户名。

CONNECTION LIMIT \$1 *limit* \$1 UNLIMITED \$1   
允许用户同时打开的数据库连接的最大数量。此限制不适用于超级用户。使用 UNLIMITED 关键字设置允许的并行连接的最大数量。可能对每个用户的连接数量也会施加限制。有关更多信息，请参阅 [CREATE USER](r_CREATE_USER.md)。默认为 UNLIMITED。要查看当前连接，请查询 [STV\$1SESSIONS](r_STV_SESSIONS.md) 系统视图。  
如果用户及数据库连接限制均适用，当用户尝试连接时，必须有一个同时低于这两个限制的未使用的连接槽可用。

COLLATE \$1 CASE\$1SENSITIVE \$1 CS \$1 CASE\$1INSENSITIVE \$1 CI \$1  
指定字符串搜索或比较是区分大小写还是不区分大小写的子句。默认为区分大小写。  
从数据共享创建数据库时，不支持 COLLATE。  
CASE\$1SENSITIVE 和 CS 可以互换，生成的结果相同。同样，CASE\$1INSENSITIVE 和 CI 可以互换，生成的结果相同。

ISOLATION LEVEL \$1 SNAPSHOT \$1 SERIALIZABLE \$1  
指定针对数据库运行查询时使用的隔离级别的子句。有关隔离级别的更多信息，请参阅[Amazon Redshift 中的隔离级别](c_serial_isolation.md)。  
+ SNAPSHOT 隔离 – 提供隔离级别，来防止出现更新和删除冲突。这是在预调配集群或无服务器命名空间中创建的数据库的默认设置。
+ SERIALIZABLE 隔离 – 为并发事务提供完全可序列性。

FROM ARN '<ARN>'  
用于创建数据库的 AWS Glue 数据库 ARN。

\$1 WITH DATA CATALOG SCHEMA '<schema>' \$1 WITH NO DATA CATALOG SCHEMA \$1  
仅当您的 CREATE DATABASE 命令也使用 FROM ARN 参数时，此参数才适用。
指定是否使用架构创建数据库以帮助访问 AWS Glue Data Catalog 中的对象。

IAM\$1ROLE \$1 default \$1 'SESSION' \$1 'arn:aws:iam::*<AWS 账户-id>*:role/*<role-name>*' \$1  
仅当您的 CREATE DATABASE 命令也使用 FROM ARN 参数时，此参数才适用。
如果您在运行 CREATE DATABASE 命令时指定与集群关联的 IAM 角色，则 Amazon Redshift 将在您对数据库运行查询时使用该角色的凭证。  
指定 `default` 关键字表示要使用设置为默认并与集群关联的 IAM 角色。  
如果您使用联合身份连接到 Amazon Redshift 集群并访问使用此命令创建的外部架构中的表，则使用 `'SESSION'`。有关使用联合身份的示例，请参阅[使用联合身份管理 Amazon Redshift 对本地资源和 Amazon Redshift Spectrum 外部表的访问权限](https://docs.aws.amazon.com/redshift/latest/mgmt/authorization-fas-spectrum.html)，其中说明了如何配置联合身份。  
使用 IAM 角色的 Amazon 资源名称（ARN），您的集群使用该角色进行身份验证和授权。IAM 角色至少必须有权在要访问的 Amazon S3 桶上执行 LIST 操作和有权在该桶包含的 Amazon S3 对象上执行 GET 操作。要了解有关在使用 AWS Glue Data Catalog 为数据共享创建数据库时使用 IAM\$1ROLE 的更多信息，请参阅[以使用者身份使用 Lake Formation 托管的数据共享](https://docs.aws.amazon.com/redshift/latest/dg/lake-formation-getting-started-consumer.html)。  
下面显示了单个 ARN 的 IAM\$1ROLE 参数字符串的语法。  

```
IAM_ROLE 'arn:aws:iam::<aws-account-id>:role/<role-name>'
```
您可以将角色串联起来，以便集群可以承担另一个 IAM 角色 (可能属于其他账户)。您最多可串联 10 个角色。有关更多信息，请参阅 [在 Amazon Redshift Spectrum 中链接 IAM 角色](c-spectrum-iam-policies.md#c-spectrum-chaining-roles)。  
 对于此 IAM 角色，请附加类似于以下内容的 IAM 权限策略。    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AccessSecret",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetResourcePolicy",
                "secretsmanager:GetSecretValue",
                "secretsmanager:DescribeSecret",
                "secretsmanager:ListSecretVersionIds"
            ],
            "Resource": "arn:aws:secretsmanager:us-west-2:123456789012:secret:my-rds-secret-VNenFy"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetRandomPassword",
                "secretsmanager:ListSecrets"
            ],
            "Resource": "*"
        }
    ]
}
```
有关创建 IAM 角色以用于联合查询的步骤，请参阅[创建密钥和 IAM 角色以使用联合查询](federated-create-secret-iam-role.md)。  
请不要在链接的角色列表中包含空格。
下面显示了串联三个角色的语法。  

```
IAM_ROLE 'arn:aws:iam::<aws-account-id>:role/<role-1-name>,arn:aws:iam::<aws-account-id>:role/<role-2-name>,arn:aws:iam::<aws-account-id>:role/<role-3-name>'
```

## 将 CREATE DATABASE 与数据共享结合使用的语法
<a name="r_CREATE_DATABASE-datashare-synopsis"></a>

以下语法描述了用于从数据共享中创建数据库以在同一 AWS 账户内共享数据的 CREATE DATABASE 命令。

```
CREATE DATABASE database_name
[ [ WITH PERMISSIONS ] FROM DATASHARE datashare_name OF [ ACCOUNT account_id ] NAMESPACE namespace_guid
```

以下语法描述了用于从数据共享中创建数据库以在 AWS 账户间共享数据的 CREATE DATABASE 命令。

```
CREATE DATABASE database_name
[ [ WITH PERMISSIONS ] FROM DATASHARE datashare_name OF ACCOUNT account_id NAMESPACE namespace_guid
```

### 将 CREATE DATABASE 与数据共享结合使用的参数
<a name="r_CREATE_DATABASE-parameters-datashare"></a>

FROM DATASHARE   
指示数据库所在位置的关键词。

 *datashare\$1name*   
创建使用者数据库所在的数据共享的名称。

WITH PERMISSIONS  
指定通过数据共享创建的数据库需要对象级权限才能访问各个数据库对象。如果没有此子句，则被授予对数据库的 USAGE 权限的用户或角色将自动有权访问数据库中的所有数据库对象。

 NAMESPACE *namespace\$1guid*   
指定数据共享所属的生产者命名空间的值。

ACCOUNT *account\$1id*  
指定数据共享所属的生产者账户的值。

## 用于数据共享的 CREATE DATABASE 的使用说明
<a name="r_CREATE_DATABASE-usage"></a>

作为数据库超级用户，当您使用 CREATE DATABASE 从 AWS 账户内的数据共享创建数据库时，指定 NAMESPACE 选项。ACCOUNT 选项为可选项。当您使用 CREATE DATABASE 从 AWS 账户间的数据共享创建数据库时，同时指定生产者的 ACCOUNT 和 NAMESPACE。

对于使用者集群上的数据共享，一个数据共享仅可创建一个使用者数据库。不能创建多个引用同一数据共享的使用者数据库。

## CREATE DATABASE（从 AWS Glue Data Catalog）
<a name="r_CREATE_DATABASE_data-catalog"></a>

要使用 AWS Glue 数据库 ARN 创建数据库，请在 CREATE DATABASE 命令中指定 ARN。

```
CREATE DATABASE sampledb FROM ARN <glue-database-arn> WITH NO DATA CATALOG SCHEMA;
```

或者，您也可以为 IAM\$1ROLE 参数提供一个值。有关参数和接受的值的更多信息，请参阅[参数](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_DATABASE.html#r_CREATE_DATABASE-parameters)。

以下示例演示了如何使用 IAM 角色从 ARN 创建数据库。

```
CREATE DATABASE sampledb FROM ARN <glue-database-arn> WITH NO DATA CATALOG SCHEMA IAM_ROLE <iam-role-arn>
```

```
CREATE DATABASE sampledb FROM ARN <glue-database-arn> WITH NO DATA CATALOG SCHEMA IAM_ROLE default;
```

您也可以使用 DATA CATALOG SCHEMA 创建数据库。

```
CREATE DATABASE sampledb FROM ARN <glue-database-arn> WITH DATA CATALOG SCHEMA <sample_schema> IAM_ROLE default;
```

## 创建数据库以接收零 ETL 集成的结果
<a name="r_CREATE_DATABASE-integration"></a>

要使用零 ETL 集成标识创建数据库，请在 CREATE DATABASE 命令中指定 `integration_id`。

```
CREATE DATABASE destination_db_name FROM INTEGRATION 'integration_id';
```

例如，首先从 SVV\$1INTEGRATION 中获取集成 ID；

```
SELECT integration_id FROM SVV_INTEGRATION;
```

然后使用检索到的其中一个集成 ID 创建接收零 ETL 集成的数据库。

```
CREATE DATABASE sampledb FROM INTEGRATION 'a1b2c3d4-5678-90ab-cdef-EXAMPLE11111';
```

例如，当需要零 ETL 集成源数据库时，请指定。

```
CREATE DATABASE sampledb FROM INTEGRATION 'a1b2c3d4-5678-90ab-cdef-EXAMPLE11111' DATABASE sourcedb;
```

您还可以设置数据库的刷新间隔。例如，将来自零 ETL 集成源的数据的刷新间隔设为 7200 秒：

```
CREATE DATABASE myacct_mysql FROM INTEGRATION 'a1b2c3d4-5678-90ab-cdef-EXAMPLE11111' SET REFRESH_INTERVAL 7200;
```

查询 SVV\$1INTEGRATION 目录视图，以获取零 ETL 集成的相关信息，如 integration\$1id、target\$1database、source、refresh\$1interval 等。

```
SELECT * FROM svv_integration;
```

以下示例从已启用历史记录模式的集成中创建数据库。

```
CREATE DATABASE sample_integration_db FROM INTEGRATION 'a1b2c3d4-5678-90ab-cdef-EXAMPLE11111' SET HISTORY_MODE = true;
```

## CREATE DATABASE 限制
<a name="r_CREATE_DATABASE-create-database-limits"></a>

Amazon Redshift 针对数据库强制实施以下限制：
+ 每个集群最多 60 个用户定义的数据库。
+ 数据库名称最多为 127 个字节。
+ 数据库名称不能使用保留字。

## 数据库排序规则
<a name="r_CREATE_DATABASE-collation"></a>

排序规则是一组规则，用于定义数据库引擎如何对 SQL 中的字符类型数据进行比较和排序。不区分大小写的排序规则是最常用的排序规则。Amazon Redshift 使用不区分大小写的排序规则以帮助从其他数据仓库系统迁移。凭借对不区分大小写的排序规则的本机支持，Amazon Redshift 继续使用重要的调整或优化方法，如分配键、排序键或范围限制扫描。

COLLATE 子句指定数据库中所有 CHAR 和 VARCHAR 列的默认排序规则。如果指定了 CASE\$1INSENSITIVE，则所有 CHAR 或 VARCHAR 列都使用不区分大小写的排序规则。有关排序规则的信息，请参阅[排序规则序列](c_collation_sequences.md)。

在不区分大小写的列中插入或摄取的数据将保持其原始大小写。但是所有基于比较的字符串操作，包括排序和分组都不区分大小写。模式匹配操作（如类似于的 LIKE 谓词）和正则表达式函数也不区分大小写。

以下 SQL 操作支持适用的排序规则语义：
+ 比较运算符：=、<>、<、<=、>、>=。
+ LIKE 运算符
+ ORDER BY 子句
+ GROUP BY 子句
+ 使用字符串比较的聚合函数，例如 MIN、MAX 和 LISTAGG
+ 窗口函数，如 PARTITION BY 子句和 ORDER BY 子句
+ 标量函数 greatest() 和 least()、STRPOS()、REGEXP\$1COUNT()、REGEXP\$1REPLACE()、REGEXP\$1INSTR()、REGEXP\$1SUBSTR()
+ Distinct 子句
+ UNION、INTERSECT 和 EXCEPT
+ IN LIST

对于外部查询（包括 Amazon Redshift Spectrum 和 Aurora PostgreSQL 联合查询），VARCHAR 或 CHAR 列的排序规则与当前数据库级别的排序规则相同。

以下示例将查询 Amazon Redshift Spectrum 表：

```
SELECT ci_varchar FROM spectrum.test_collation
WHERE ci_varchar = 'AMAZON';

ci_varchar
----------
amazon
Amazon
AMAZON
AmaZon
(4 rows)
```

有关如何使用数据库排序规则创建表的信息，请参阅[CREATE TABLE](r_CREATE_TABLE_NEW.md)。

有关 COLLATE 函数的信息，请参阅[COLLATE 函数](r_COLLATE.md)。

### 数据库排序规则限制
<a name="r_CREATE_DATABASE-collation-limitations"></a>

以下是在 Amazon Redshift 中使用数据库排序规则时的限制：
+ 所有系统表或视图（包括 PG 目录表和 Amazon Redshift 系统表）均区分大小写。
+ 当使用者数据库和生产者数据库具有不同的数据库级排序规则时，Amazon Redshift 不支持跨数据库和跨集群查询。
+ Amazon Redshift 不支持仅领导节点查询中不区分大小写的排序规则。

  以下示例显示了一个不受支持的不区分大小写的查询以及 Amazon Redshift 发送的错误：

  ```
  SELECT collate(usename, 'case_insensitive') FROM pg_user;
  ERROR:  Case insensitive collation is not supported in leader node only query.
  ```
+ Amazon Redshift 不支持区分大小写和不区分大小写的列之间的交互，例如比较、函数、联接或集合运算。

  以下示例显示了区分大小写和不区分大小写的列交互时出现的错误：

  ```
  CREATE TABLE test
    (ci_col varchar(10) COLLATE case_insensitive,
     cs_col varchar(10) COLLATE case_sensitive,
     cint int,
     cbigint bigint);
  ```

  ```
  SELECT ci_col = cs_col FROM test;
  ERROR:  Query with different collations is not supported yet.
  ```

  ```
  SELECT concat(ci_col, cs_col) FROM test;
  ERROR:  Query with different collations is not supported yet.
  ```

  ```
  SELECT ci_col FROM test UNION SELECT cs_col FROM test;
  ERROR:  Query with different collations is not supported yet.
  ```

  ```
  SELECT * FROM test a, test b WHERE a.ci_col = b.cs_col;
  ERROR:  Query with different collations is not supported yet.
  ```

  ```
  Select Coalesce(ci_col, cs_col) from test;
  ERROR:  Query with different collations is not supported yet.
  ```

  ```
  Select case when cint > 0 then ci_col else cs_col end from test;
  ERROR:  Query with different collations is not supported yet.
  ```

要使这些查询起作用，请使用 COLLATE 函数将一个列的排序规则转换为与另一列匹配。有关更多信息，请参阅 [COLLATE 函数](r_COLLATE.md)。

## 示例
<a name="r_CREATE_DATABASE-examples"></a>

**创建数据库**  
以下示例创建名为 TICKIT 的数据库并将所有权授予用户 DWUSER。

```
create database tickit
with owner dwuser;
```

要查看有关数据库的详细信息，请查询 PG\$1DATABASE\$1INFO 目录表。

```
select datname, datdba, datconnlimit
from pg_database_info
where datdba > 1;

 datname     | datdba | datconnlimit
-------------+--------+-------------
 admin       |    100 | UNLIMITED
 reports     |    100 | 100
 tickit      |    100 | 100
```

以下示例使用 SNAPSHOT 隔离级别创建名为 **sampledb** 的数据库。

```
CREATE DATABASE sampledb ISOLATION LEVEL SNAPSHOT;
```

以下示例从数据共享 salesshare 中创建了数据库 sales\$1db。

```
CREATE DATABASE sales_db FROM DATASHARE salesshare OF NAMESPACE '13b8833d-17c6-4f16-8fe4-1a018f5ed00d';
```

### 数据库排序规则示例
<a name="r_CREATE_DATABASE-collation-examples"></a>

**创建不区分大小写的数据库**  
以下示例将创建 `sampledb` 数据库、创建 `T1` 表，并将数据插入 `T1` 表中。

```
create database sampledb collate case_insensitive;
```

连接到您刚刚使用 SQL 客户端创建的新数据库。使用 Amazon Redshift 查询编辑器 v2 时，在**编辑器**中选择 `sampledb`。使用 RSQL 时，请使用如下命令。

```
\connect sampledb;
```

```
CREATE TABLE T1 (
  col1 Varchar(20) distkey sortkey
);
```

```
INSERT INTO T1 VALUES ('bob'), ('john'), ('Mary'), ('JOHN'), ('Bob');
```

然后，查询查找含有 `John` 的结果。

```
SELECT * FROM T1 WHERE col1 = 'John';

 col1
 ------
 john
 JOHN
(2 row)
```

**按不区分大小写的顺序排序**  
以下示例显示了表 T1 中不区分大小写的排序。*Bob* 与 *bob* 或 *John* 与 *john* 的排序具有不确定性，因为它们在不区分大小写的列中是相等的。

```
SELECT * FROM T1 ORDER BY 1;

 col1
 ------
 bob
 Bob
 JOHN
 john
 Mary
(5 rows)
```

同样，以下示例显示了 GROUP BY 子句中不区分大小写的排序。*Bob* 和 *bob* 是相等的，并且属于同一个组。结果中显示哪一个是不确定的。

```
SELECT col1, count(*) FROM T1 GROUP BY 1;

 col1 | count
 -----+------
 Mary |  1
 bob  |  2
 JOHN |  2
(3 rows)
```

**使用窗口函数对不区分大小写的列进行查询**  
以下示例在不区分大小写的列上查询窗口函数。

```
SELECT col1, rank() over (ORDER BY col1) FROM T1;

 col1 | rank
 -----+------
 bob  |   1
 Bob  |   1
 john |   3
 JOHN |   3
 Mary |   5
(5 rows)
```

**使用 DISTINCT 关键词进行查询**  
以下示例查询带有 DISTINCT 关键词的 `T1` 表。

```
SELECT DISTINCT col1 FROM T1;

 col1
 ------
 bob
 Mary
 john
(3 rows)
```

**使用 UNION 子句进行查询**  
以下示例显示来自表 `T1` 和 `T2` 的 UNION 的结果。

```
CREATE TABLE T2 AS SELECT * FROM T1;
```

```
SELECT col1 FROM T1 UNION SELECT col1 FROM T2;

 col1
 ------
 john
 bob
 Mary
(3 rows)
```

# CREATE DATASHARE
<a name="r_CREATE_DATASHARE"></a>

在当前数据库中创建一个新数据共享。此数据共享的拥有者为 CREATE DATASHARE 命令的发布者。

Amazon Redshift 将每个数据共享与一个 Amazon Redshift 数据库相关联。您只能将关联数据库中的对象添加到数据共享中。您可以在同一个 Amazon Redshift 数据库上创建多个数据共享。

有关数据共享的信息，请参阅[Amazon Redshift 中的数据共享](datashare-overview.md)。

要查看有关数据共享的信息，请使用[SHOW DATASHARES](r_SHOW_DATASHARES.md)。

## 所需的权限
<a name="r_CREATE_DATASHARE-privileges"></a>

以下是 CREATE DATASHARE 所需的权限：
+ Superuser
+ 具有 CREATE DATASHARE 权限的用户
+ 数据库拥有者

## 语法
<a name="r_CREATE_DATASHARE-synopsis"></a>

```
CREATE DATASHARE datashare_name
[[SET] PUBLICACCESSIBLE [=] TRUE | FALSE ];
```

## 参数
<a name="r_CREATE_DATASHARE-parameters"></a>

*datashare\$1name*  
数据共享的名称。数据共享名称在集群命名空间中必须是唯一的。

[[SET] PUBLICACCESSIBLE]  
指定是否可以将数据共享共享给可公开访问的集群的子句。  
`SET PUBLICACCESSIBLE` 的默认值为 `FALSE`。

## 使用说明
<a name="r_CREATE_DATASHARE_usage"></a>

预设情况下，数据共享的拥有者仅拥有共享，而不拥有共享中的对象。

只有超级用户和数据库拥有者才能使用 CREATE DATASHARE 并将 ALTER 权限委派给其他用户或组。

## 示例
<a name="r_CREATE_DATASHARE_examples"></a>

以下示例创建了数据共享 `salesshare`。

```
CREATE DATASHARE salesshare;
```

以下示例创建了 AWS Data Exchange 管理的数据共享 `demoshare`。

```
CREATE DATASHARE demoshare SET PUBLICACCESSIBLE TRUE, MANAGEDBY ADX;
```

# CREATE EXTERNAL FUNCTION
<a name="r_CREATE_EXTERNAL_FUNCTION"></a>

根据 Amazon Redshift 的 AWS Lambda 创建标量用户定义函数 (UDF)。有关 Lambda 用户定义函数的更多信息，请参阅[标量 Lambda UDF](udf-creating-a-lambda-sql-udf.md)。

## 所需的权限
<a name="r_CREATE_EXTERNAL_FUNCTION-privileges"></a>

以下是 CREATE EXTERNAL FUNCTION 所需的权限：
+ Superuser
+ 具有 CREATE [ OR REPLACE ] EXTERNAL FUNCTION 权限的用户

## 语法
<a name="r_CREATE_EXTERNAL_FUNCTION-synopsis"></a>

```
CREATE [ OR REPLACE ] EXTERNAL FUNCTION external_fn_name ( [data_type] [, ...] )
RETURNS data_type
{ VOLATILE | STABLE }
LAMBDA 'lambda_fn_name'
IAM_ROLE { default | ‘arn:aws:iam::<AWS 账户-id>:role/<role-name>’
RETRY_TIMEOUT milliseconds
MAX_BATCH_ROWS count
MAX_BATCH_SIZE size [ KB | MB ];
```

## 参数
<a name="r_CREATE_EXTERNAL_FUNCTION-parameters"></a>

OR REPLACE  
一个子句，指定如果某个函数与已存在的此函数具有相同的名称和输入参数数据类型或*签名*，则替换现有的函数。您只能将某个函数替换为定义一组相同数据类型的新函数。您必须是超级用户才能替换函数。  
如果您定义的函数与现有函数具有相同的名称，但签名不同，则创建新的函数。换而言之，函数名称将会重载。有关更多信息，请参阅 [重载函数名称](udf-naming-udfs.md#udf-naming-overloading-function-names)。

*external\$1fn\$1name*  
外部函数的名称。如果您指定 schema 名称（例如 myschema.myfunction），则使用指定的 schema 创建函数。否则，将在当前 schema 中创建该函数。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。  
我们建议您将所有 UDF 名称添加前缀 `f_`。Amazon Redshift 保留 `f_` 前缀，用于 UDF 名称。通过使用 `f_` 前缀，您可以帮助确保您的 UDF 名称现在或将来不会与 Amazon Redshift 的任何内置 SQL 函数名称发生冲突。有关更多信息，请参阅 [防止 UDF 命名冲突](udf-naming-udfs.md)。

*data\$1type*  
输入参数的数据类型。有关更多信息，请参阅[标量 Python UDF](udf-creating-a-scalar-udf.md)和[标量 Lambda UDF](udf-creating-a-lambda-sql-udf.md)。

RETURNS *data\$1type*  
函数返回的值的数据类型。RETURNS 数据类型可以是任何标准的 Amazon Redshift 数据类型。有关更多信息，请参阅[标量 Python UDF](udf-creating-a-scalar-udf.md)和[标量 Lambda UDF](udf-creating-a-lambda-sql-udf.md)。

VOLATILE \$1 STABLE  
通知查询优化程序有关函数的不稳定性。  
要获得最大程度的优化，将函数标记为其有效的最严格稳定性类别。按照严格性顺序，从最不严格的开始，稳定性类别如下所示：  
+ VOLATILE
+ STABLE
VOLATILE  
对于相同的参数，函数会对连续的调用返回不同的结果，甚至对于单个语句中的行也是如此。查询优化器无法对不稳定函数的行为做出假设。使用不稳定函数的查询必须对每个输入重新计算该函数。  
STABLE  
对于相同的参数，可保证函数对在单个语句内处理的所有后续调用返回相同的结果。在不同的语句中调用时，函数可能会返回不同的结果。通过这一类别，优化器可以减少在单个语句中调用函数的次数。  
请注意，如果所选的严格性对函数无效，则存在优化器可能会基于这种严格性跳过某些调用的风险。这可能会导致结果集不正确。  
Lambda UDF 目前不支持 IMMUTABLE 子句。

LAMBDA *'lambda\$1fn\$1name'*  
 Amazon Redshift 调用的函数的名称。  
有关创建 AWS Lambda 函数的步骤，请参阅《AWS Lambda 开发人员指南》**中的[使用控制台创建 Lambda 函数](https://docs.aws.amazon.com/lambda/latest/dg/getting-started-create-function.html)。  
有关 Lambda 函数所需权限的信息，请参阅《AWS Lambda 开发人员指南》**中的 [AWS Lambda 权限](https://docs.aws.amazon.com/lambda/latest/dg/lambda-permissions.html)。

IAM\$1ROLE \$1 default \$1 ‘arn:aws:iam::*<AWS 账户-id>*:role/*<role-name>*’   
使用默认关键字让 Amazon Redshift 使用 IAM 角色，该角色设置为默认值并在 CREATE EXTERNAL FUNCTION 命令运行时与集群关联。  
使用 IAM 角色的 Amazon 资源名称（ARN），您的集群使用该角色进行身份验证和授权。CREATE EXTERNAL FUNCTION 命令被授权通过此 IAM 角色调用 Lambda 函数。如果您的集群具有有权调用所附加 Lambda 函数的现有 IAM 角色，您可以替换您的角色的 ARN。有关更多信息，请参阅 [配置 Lambda UDF 的授权参数](udf-creating-a-lambda-sql-udf.md#udf-lambda-authorization)。  
以下显示 IAM\$1ROLE 参数的语法。  

```
IAM_ROLE 'arn:aws:iam::aws-account-id:role/role-name'
```

RETRY\$1TIMEOUT *毫秒*   
Amazon Redshift 用于重试退避延迟的总时间（以毫秒为单位）。  
Amazon Redshift 不会立即重试任何失败的查询，而是执行退避并等待一定时间间隔再重试。然后，Amazon Redshift 将重试请求，以重新运行失败的查询，直到所有延迟的总和等于或超过您指定的 RETRY\$1TIMEOUT 值。默认值为 20000 毫秒。  
当调用 Lambda 函数时，Amazon Redshift 会重试接收 `TooManyRequestsException`、`EC2ThrottledException` 和 `ServiceException` 等错误的查询。  
您可以将 RETRY\$1TIMEOUT 参数设置为 0 毫秒，以防止对 Lambda UDF 进行任何重试。

MAX\$1BATCH\$1ROWS *count*  
 Amazon Redshift 在单个批处理请求中为单个 lambda 调用发送的最大行数。  
 此参数的最小值为 1。最大值为 INT\$1MAX，即 2,147,483,647。  
 此参数为可选的。默认值为 INT\$1MAX，即 2,147,483,647。

MAX\$1BATCH\$1SIZE *size* [ KB \$1 MB ]   
 Amazon Redshift 在单个批处理请求中为单个 lambda 调用发送的数据负载的最大大小。  
 此参数的最小值为 1 KB。最大值为 5 MB。  
 此参数的默认值为 5 MB。  
 KB 和 MB 是可选的。如果您未设置计量单位，则 Amazon Redshift 默认使用 KB。

## 使用说明
<a name="r_CREATE_FUNCTION-usage-notes"></a>

创建 Lambda UDF 时请考虑以下几点：
+ Lambda 函数调用输入参数的顺序不是固定的或有保证的。这可能因正在运行的查询实例而异，具体取决于集群配置。
+ 不能保证函数对每个输入参数应用一次，且只应用一次。Amazon Redshift 和 AWS Lambda 之间的交互可能会导致使用相同输入的重复调用。

## 示例
<a name="r_CREATE_FUNCTION-examples"></a>

以下是使用标量 Lambda 用户定义函数 (UDF) 的示例。

### 使用 Node.js Lambda 函数的标量 Lambda UDF 示例
<a name="r_CREATE_FUNCTION-lambda-example-node"></a>

以下示例创建一个名为 `exfunc_sum` 的外部函数，它将两个整数作为输入参数。此函数以整数输出形式返回总和。要调用的 Lambda 函数的名称为 `lambda_sum`。用于此 Lambda 函数的语言是 Node.js 12.x。确保指定 IAM 角色。此示例使用 `'arn:aws:iam::123456789012:user/johndoe'` 作为 IAM 角色。

```
CREATE EXTERNAL FUNCTION exfunc_sum(INT,INT)
RETURNS INT
VOLATILE
LAMBDA 'lambda_sum'
IAM_ROLE 'arn:aws:iam::123456789012:role/Redshift-Exfunc-Test';
```

Lambda 函数接受请求负载并对每一行进行迭代。将单行中的所有值相加以计算该行的总和，并将其保存在响应数组中。结果数组中的行数与请求负载中接收的行数相似。

JSON 响应负载必须在“results”字段中包含结果数据，才能被外部函数识别。发送到 Lambda 函数的请求中的参数字段包含数据负载。在批处理请求的情况下，数据负载中可能有多行。以下 Lambda 函数对请求数据负载中的所有行进行迭代。它还分别对一行中的所有值进行迭代。

```
exports.handler = async (event) => {
    // The 'arguments' field in the request sent to the Lambda function contains the data payload.
    var t1 = event['arguments'];

    // 'len(t1)' represents the number of rows in the request payload.
    // The number of results in the response payload should be the same as the number of rows received.
    const resp = new Array(t1.length);

    // Iterating over all the rows in the request payload.
    for (const [i, x] of t1.entries())
    {
        var sum = 0;
        // Iterating over all the values in a single row.
        for (const y of x) {
            sum = sum + y;
        }
        resp[i] = sum;
    }
    // The 'results' field should contain the results of the lambda call.
    const response = {
        results: resp
    };
    return JSON.stringify(response);
};
```

以下示例使用文本值调用外部函数。

```
select exfunc_sum(1,2);
exfunc_sum
------------
 3
(1 row)
```

以下示例创建一个名为 t\$1sum 的表（其中包含整数数据类型的两个列 c1 和 c2）并插入两行数据。然后通过传递此表的列名称来调用外部函数。这两个表行作为单个 Lambda 调用在请求负载中的批处理请求中发送。

```
CREATE TABLE t_sum(c1 int, c2 int);
INSERT INTO t_sum VALUES (4,5), (6,7);
SELECT exfunc_sum(c1,c2) FROM t_sum;
 exfunc_sum
---------------
 9
 13
(2 rows)
```

### 使用 RETRY\$1TIMEOUT 属性的标量 Lambda UDF 示例
<a name="r_CREATE_FUNCTION-lambda-example-retry"></a>

在以下部分中，您可以找到如何在 Lambda UDF 中使用 RETRY\$1TIMEOUT 属性的示例。

AWS Lambda 函数具有并发限制，您可以为每个函数设置这些限制。有关并发限制的更多信息，请参阅《AWS Lambda 开发人员指南》**中的[为 Lambda 函数管理并发](https://docs.aws.amazon.com/lambda/latest/dg/configuration-concurrency.html)和 AWS 计算博客上的博客文章 [Managing AWS Lambda Function Concurrency](https://aws.amazon.com/blogs/compute/managing-aws-lambda-function-concurrency)。

当 Lambda UDF 服务的请求数超过并发限制时，新请求将接收 `TooManyRequestsException` 错误。Lambda UDF 会重试此错误，直到发送到 Lambda 函数的请求之间的所有延迟总和等于或超过您设置的 RETRY\$1TIMEOUT 值。默认的 RETRY\$1TIMEOUT 值为 20000 毫秒。

下面的示例使用一个名为 `exfunc_sleep_3` 的 Lambda 函数。此函数接受请求负载，对每一行进行迭代，并将输入转换为大写。然后它会睡眠 3 秒钟并返回结果。此 Lambda 函数使用的语言是 Python 3.8。

结果数组中的行数与请求负载中接收的行数相似。JSON 响应负载必须在 `results` 字段中包含结果数据，才能被外部函数识别。发送到 Lambda 函数的请求中的 `arguments` 字段包含数据负载。在批处理请求的情况下，数据负载中可能有多行。

在保留并发中，此函数的并发限制被专门设置为 1，以演示 RETRY\$1TIMEOUT 属性的使用情况。当属性设置为 1 时，Lambda 函数一次只能处理一个请求。

```
import json
import time
def lambda_handler(event, context):
    t1 = event['arguments']
    # 'len(t1)' represents the number of rows in the request payload.
    # The number of results in the response payload should be the same as the number of rows received.
    resp = [None]*len(t1)

    # Iterating over all rows in the request payload.
    for i, x in enumerate(t1):
        # Iterating over all the values in a single row.
        for j, y in enumerate(x):
            resp[i] = y.upper()

    time.sleep(3)
    ret = dict()
    ret['results'] = resp
    ret_json = json.dumps(ret)
    return ret_json
```

以下两个附加示例对 RETRY\$1TIMEOUT 属性进行了说明。它们各自调用了一个 Lambda UDF。在调用 Lambda UDF 时，每个示例都运行相同的 SQL 查询，以便同时从两个并发数据库会话调用 Lambda UDF。当第一个调用 Lambda UDF 的查询由 UDF 提供时，第二个查询会收到 `TooManyRequestsException` 错误。出现此结果是因为您将 UDF 中的保留并发专门设置为 1。有关如何为 Lambda 函数设置保留并发的信息，请参阅[配置预留并发](https://docs.aws.amazon.com/lambda/latest/dg/configuration-concurrency.html#configuration-concurrency-reservedconfiguration-concurrency-reserved)。

下面的第一个示例将 Lambda UDF 的 RETRY\$1TIMEOUT 属性设置为 0 毫秒。如果 Lambda 请求收到来自 Lambda 函数的任何异常，则 Amazon Redshift 不会进行任何重试。出现此结果的原因是 RETRY\$1TIMEOUT 属性被设置为 0。

```
CREATE OR REPLACE EXTERNAL FUNCTION exfunc_upper(varchar)
RETURNS varchar
VOLATILE
LAMBDA 'exfunc_sleep_3'
IAM_ROLE 'arn:aws:iam::123456789012:role/Redshift-Exfunc-Test'
RETRY_TIMEOUT 0;
```

将 RETRY\$1TIMEOUT 设置为 0 时，您可以从单独的数据库会话运行以下两个查询以查看不同的结果。

使用 Lambda UDF 的第一个 SQL 查询成功运行。

```
select exfunc_upper('Varchar');
 exfunc_upper
 --------------
 VARCHAR
(1 row)
```

同时从单独的数据库会话运行的第二个查询将收到 `TooManyRequestsException` 错误。

```
select exfunc_upper('Varchar');
ERROR:  Rate Exceeded.; Exception: TooManyRequestsException; ShouldRetry: 1
DETAIL:
-----------------------------------------------
error:  Rate Exceeded.; Exception: TooManyRequestsException; ShouldRetry: 1
code:      32103
context:query:     0
location:  exfunc_client.cpp:102
process:   padbmaster [pid=26384]
-----------------------------------------------
```

下面的第二个示例将 Lambda UDF 的 RETRY\$1TIMEOUT 属性设置为 3000 毫秒。即使同时运行第二个查询，Lambda UDF 也会重试，直到总延迟为 3000 毫秒。因此，两个查询都成功运行。

```
CREATE OR REPLACE EXTERNAL FUNCTION exfunc_upper(varchar)
RETURNS varchar
VOLATILE
LAMBDA 'exfunc_sleep_3'
IAM_ROLE 'arn:aws:iam::123456789012:role/Redshift-Exfunc-Test'
RETRY_TIMEOUT 3000;
```

将 RETRY\$1TIMEOUT 被设置为 3000 时，您可以从单独的数据库会话运行以下两个查询以查看相同的结果。

运行 Lambda UDF 的第一个 SQL 查询成功运行。

```
select exfunc_upper('Varchar');
 exfunc_upper
 --------------
 VARCHAR
(1 row)
```

第二个查询同时运行，且 Lambda UDF 重试，直到总延迟为 3000 毫秒。

```
select exfunc_upper('Varchar');
 exfunc_upper
--------------
 VARCHAR
(1 row)
```

### 使用 Python Lambda 函数的标量 Lambda UDF 示例
<a name="r_CREATE_FUNCTION-lambda-example-python"></a>

以下示例创建名为 `exfunc_multiplication` 的外部函数，然后将数字相乘并返回整数。此示例合并了 Lambda 响应中的 success 和 `error_msg` 字段。当乘法结果中存在整数溢出时，success 字段设置为 false，且 `error_msg` 消息设置为 `Integer multiplication overflow`。`exfunc_multiplication` 函数将三个整数作为输入参数，并将总和作为整数输出返回。

被调用的 Lambda 函数的名称为 `lambda_multiplication`。此 Lambda 函数使用的语言是 Python 3.8。确保指定 IAM 角色。

```
CREATE EXTERNAL FUNCTION exfunc_multiplication(int, int, int)
RETURNS INT
VOLATILE
LAMBDA 'lambda_multiplication'
IAM_ROLE 'arn:aws:iam::123456789012:role/Redshift-Exfunc-Test';
```

Lambda 函数接受请求负载并对每一行进行迭代。将单行中的所有值相乘以计算该行的结果，并将其保存在响应列表中。此示例使用默认设置为 true 的 Boolean success 值。如果行的乘法结果具有整数溢出，则 success 值设置为 false。然后，迭代循环中断。

创建响应负载时，如果 success 值为 false，则以下 Lambda 函数将 `error_msg` 字段添加到负载中。它还将错误消息设置为 `Integer multiplication overflow`。如果 success 值为 true，则结果数据将添加到结果字段中。结果数组（如果有）中的行数与请求负载中接收的行数相似。

发送到 Lambda 函数的请求中的参数字段包含数据负载。在批处理请求的情况下，数据负载中可能有多行。以下 Lambda 函数对请求数据负载中的所有行进行迭代，并分别对一行中的所有值进行迭代。

```
import json
def lambda_handler(event, context):
    t1 = event['arguments']
    # 'len(t1)' represents the number of rows in the request payload.
    # The number of results in the response payload should be the same as the number of rows received.
    resp = [None]*len(t1)

    # By default success is set to 'True'.
    success = True
    # Iterating over all rows in the request payload.
    for i, x in enumerate(t1):
        mul = 1
        # Iterating over all the values in a single row.
        for j, y in enumerate(x):
            mul = mul*y

        # Check integer overflow.
        if (mul >= 9223372036854775807 or mul <= -9223372036854775808):
            success = False
            break
        else:
            resp[i] = mul
    ret = dict()
    ret['success'] = success
    if not success:
        ret['error_msg'] = "Integer multiplication overflow"
    else:
        ret['results'] = resp
    ret_json = json.dumps(ret)

    return ret_json
```

以下示例使用文本值调用外部函数。

```
SELECT exfunc_multiplication(8, 9, 2);
  exfunc_multiplication
---------------------------
          144
(1 row)
```

以下示例创建一个名为 t\$1multi 的表，其中包含整数数据类型的三个列 c1、c2 和 c3。通过传递此表的列名称来调用外部函数。以导致整数溢出的方式插入数据，从而显示错误的传播方式。

```
CREATE TABLE t_multi (c1 int, c2 int, c3 int);
INSERT INTO t_multi VALUES (2147483647, 2147483647, 4);
SELECT exfunc_multiplication(c1, c2, c3) FROM t_multi;
DETAIL:
  -----------------------------------------------
  error:  Integer multiplication overflow
  code:      32004context:
  context:
  query:     38
  location:  exfunc_data.cpp:276
  process:   query2_16_38 [pid=30494]
  -----------------------------------------------
```

# CREATE EXTERNAL MODEL
<a name="r_create_external_model"></a>

**Topics**
+ [CREATE EXTERNAL MODEL 的先决条件](#r_create_external_model_prereqs)
+ [所需的权限](#r_simple_create_model-privileges)
+ [成本控制](#r_create_model_cost)
+ [CREATE EXTERNAL MODEL 语法](#r_create_external_model_syntax)
+ [CREATE EXTERNAL MODEL 参数和设置](#r_create_external_model_parameters_settings)
+ [CREATE EXTERNAL MODEL 推理函数参数](#r_create_external_model_if_parameters)

## CREATE EXTERNAL MODEL 的先决条件
<a name="r_create_external_model_prereqs"></a>

在使用 CREATE EXTERNAL MODEL 语句之前，请完成 [用于使用 Amazon Redshift ML 的集群设置](getting-started-machine-learning.md#cluster-setup) 中的先决条件。下面简要概述了这些先决条件。
+ 使用 AWS 管理控制台或 AWS 命令行界面 (AWS CLI) 创建 Amazon Redshift 集群。
+ 在创建集群时附加 AWS Identity and Access Management (IAM) policy。
+ 要允许 Amazon Redshift 和 Amazon Bedrock 代入角色以便与其它服务交互，请向 IAM 角色添加相应的信任策略。
+ 支持从 Amazon Bedrock 控制台访问您要使用的特定 LLM。
+ （可选）如果您遇到来自 Amazon Bedrock 的节流异常（例如 `Too many requests, please wait before trying again`），即使数据量很少，也可以在 Amazon Bedrock 账户的**服务配额**下检查配额。检查所应用的账户级配额是否至少与针对您正在使用的模型的 **InvokeModel** 请求的 AWS 默认配额值相同。

有关 IAM 角色、信任策略和其他先决条件的详细信息，请参阅[用于使用 Amazon Redshift ML 的集群设置](getting-started-machine-learning.md#cluster-setup)。

## 所需的权限
<a name="r_simple_create_model-privileges"></a>

以下是 CREATE EXTERNAL MODEL 所需的权限：
+ Superuser
+ 具有 CREATE MODEL 权限的用户
+ 具有 GRANT CREATE MODEL 权限的角色

## 成本控制
<a name="r_create_model_cost"></a>

 Amazon Redshift ML 使用现有集群资源创建预测模型，因此您无需支付额外费用。不过，AWS 会根据您选择的模型收取使用 Amazon Bedrock 的费用。有关更多信息，请参阅[使用 Amazon Redshift ML 的成本](https://docs.aws.amazon.com/redshift/latest/dg/cost.html)。

## CREATE EXTERNAL MODEL 语法
<a name="r_create_external_model_syntax"></a>

以下是 CREATE EXTERNAL MODEL 语句的完整语法。

```
CREATE EXTERNAL MODEL model_name 
FUNCTION function_name
IAM_ROLE {default/'arn:aws:iam::<account-id>:role/<role-name>'}
MODEL_TYPE BEDROCK
SETTINGS (
   MODEL_ID model_id
   [, PROMPT 'prompt prefix']
   [, SUFFIX 'prompt suffix']
   [, REQUEST_TYPE {RAW|UNIFIED}]
   [, RESPONSE_TYPE {VARCHAR|SUPER}]
);
```

`CREATE EXTERNAL MODEL` 命令会创建一个推理函数，用于生成内容。

下面是 `CREATE EXTERNAL MODEL` 使用 `RAW` `REQUEST_TYPE` 创建的推理函数的语法：

```
SELECT inference_function_name(request_super) 
[FROM table];
```

下面是 `CREATE EXTERNAL MODEL` 使用 `UNIFIED` `REQUEST_TYPE` 创建的推理函数的语法：

```
SELECT inference_function_name(input_text, [, inference_config [, additional_model_request_fields]])
[FROM table];
```

有关如何使用推理函数的信息，请参阅 [为 Amazon Redshift ML 与 Amazon Bedrock 的集成使用外部模型](machine-learning-br.md#machine-learning-br-use)。

## CREATE EXTERNAL MODEL 参数和设置
<a name="r_create_external_model_parameters_settings"></a>

此部分介绍 `CREATE EXTERNAL MODEL` 命令的参数和设置。

**Topics**
+ [CREATE EXTERNAL MODEL 参数](#r_create_external_model_parameters)
+ [CREATE EXTERNAL MODEL 设置](#r_create_external_model_settings)

### CREATE EXTERNAL MODEL 参数
<a name="r_create_external_model_parameters"></a>

model\$1name  
外部模型的名称。schema 中的模型名称必须是唯一的。

FUNCTION *function\$1name (data\$1type [,...] )*  
`CREATE EXTERNAL MODEL` 创建的推理函数的名称。您可以使用推理函数向 Amazon Bedrock 发送请求并检索 ML 生成的文本。

IAM\$1ROLE * \$1 default \$1 'arn:aws:iam::<account-id>:role/<role-name>' \$1*  
Amazon Redshift 用于访问 Amazon Bedrock 的 IAM 角色。有关 IAM 角色的信息，请参阅 [为 Amazon Redshift ML 与 Amazon Bedrock 的集成创建或更新 IAM 角色](machine-learning-br.md#machine-learning-br-iam)。

MODEL\$1TYPE BEDROCK  
指定模型类型。唯一有效值为 `BEDROCK`。

SETTINGS ( MODEL\$1ID model\$1id [,...] )  
指定外部模型设置。详见下一节。

### CREATE EXTERNAL MODEL 设置
<a name="r_create_external_model_settings"></a>

MODEL\$1ID model\$1id  
外部模型的标识符，例如 `anthropic.claude-v2`。有关 Amazon Bedrock 模型 ID 的信息，请参阅 [Amazon Bedrock 模型 ID](https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids.html)。

PROMPT 'prompt prefix'  
指定 Amazon Redshift 添加到每个推理请求开头的静态提示。只有在 `REQUEST_TYPE` 为 `UNIFIED` 时受支持。

SUFFIX 'prompt suffix'  
指定 Amazon Redshift 添加到每个推理请求末尾的静态提示。只有在 `REQUEST_TYPE` 为 `UNIFIED` 时受支持。

REQUEST\$1TYPE \$1 RAW \$1 UNIFIED \$1  
指定发送到 Amazon Bedrock 的请求的格式。有效值包括：  
+ **RAW**：推理函数以单个 super 值作为输入，并始终返回一个 super 值。super 值的格式取决于所选的 Amazon Bedrock 模型。super 是一种预测模型，它将多种算法结合在一起，产生一个改进的预测结果。
+ **UNIFIED**：推理函数使用统一 API。所有模型都与 Amazon Bedrock 拥有统一一致的接口。这适用于所有支持消息的模型。此值是默认值。

  有关更多信息，请参阅 *Amazon Bedrock API 文档*中的 [Converse API 文档](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_Converse.html)。

RESPONSE\$1TYPE \$1 VARCHAR \$1 SUPER \$1  
指定响应的格式。如果 `REQUEST_TYPE` 为 `RAW`，则需要 `RESPONSE_TYPE`，而且唯一有效的值为 `SUPER`。对于所有其它 `REQUEST TYPE` 值，默认值为 `VARCHAR`，而且 `RESPONSE_TYPE` 是可选的。有效值包括：  
+ **VARCHAR**：Amazon Redshift 仅返回模型生成的文本响应。
+ **SUPER**：Amazon Redshift 会将模型生成的整个响应 JSON 作为 super 返回。这包括文本响应、停止原因等信息，以及模型输入和输出标记的使用情况。super 是一种预测模型，它将多种算法结合在一起，产生一个改进的预测结果。

## CREATE EXTERNAL MODEL 推理函数参数
<a name="r_create_external_model_if_parameters"></a>

此部分介绍 `CREATE EXTERNAL MODEL` 命令创建的推理函数的有效参数。

### `REQUEST_TYPE` 为 `RAW` 的 CREATE EXTERNAL MODEL 推理函数参数
<a name="r_create_external_model_if_parameters_raw"></a>

当 `REQUEST_TYPE` 为 `RAW` 时创建的推理函数有一个 super 输入参数，并且始终返回 super 数据类型。输入 super 的语法遵循从 Amazon Bedrock 中选择的特定模型的请求语法。

### `REQUEST_TYPE` 为 `UNIFIED` 的 CREATE EXTERNAL MODEL 推理函数参数
<a name="r_create_external_model_if_parameters_unified"></a>

input\$1text  
Amazon Redshift 发送给 Amazon Bedrock 的文本。

inference\$1config  
一个 super 值，其中包含 Amazon Redshift 发送给 Amazon Bedrock 的可选参数。包括以下参数：  
+ maxTokens
+ stopSequences
+ temperature
+ topP
这些参数均为可选参数，且区分大小写。有关这些参数的信息，请参阅《Amazon Bedrock API 参考》**中的 [InferenceConfiguration](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InferenceConfiguration.html)。

# CREATE EXTERNAL SCHEMA
<a name="r_CREATE_EXTERNAL_SCHEMA"></a>

在当前数据库中创建一个新外部 schema。您可以使用此外部 schema 连接到 Amazon RDS for PostgreSQL 或 Amazon Aurora PostgreSQL 兼容版本数据库。您还可以创建引用外部数据目录（如 AWS Glue、Athena）中的数据库或 Apache Hive 元存储（如 Amazon EMR）中的数据库的外部 schema。

此 schema 的所有者为 CREATE EXTERNAL SCHEMA 命令的发布者。要移交外部 schema 的所有权，请使用 [ALTER SCHEMA](r_ALTER_SCHEMA.md) 更改所有者。要为其他用户或用户组授予架构的访问权限，请使用 [GRANT](r_GRANT.md) 命令。

您无法针对外部表的权限使用 GRANT 或 REVOKE 命令。相反，您可以授予或撤销对外部 schema 的权限。

**注意**  
如果您当前在 Amazon Athena 数据目录中有 Redshift Spectrum 外部表，则可以将您的 Athena 数据目录迁移到 AWS Glue Data Catalog。要将 AWS Glue Data Catalog 用于 Redshift Spectrum，您可能需要更改您的 AWS Identity and Access Management (IAM) 策略。有关更多信息，请参阅《Athena 用户指南》**中的[升级到 AWS Glue Data Catalog](https://docs.aws.amazon.com/athena/latest/ug/glue-athena.html#glue-upgrade)。

要查看外部 schema 的详细信息，请查询 [SVV\$1EXTERNAL\$1SCHEMAS](r_SVV_EXTERNAL_SCHEMAS.md) 系统视图。

## 语法
<a name="r_CREATE_EXTERNAL_SCHEMA-synopsis"></a>

以下语法描述了用于使用外部数据目录引用数据的 CREATE EXTERNAL SCHEMA 命令。有关更多信息，请参阅 [Amazon Redshift Spectrum](c-using-spectrum.md)。

```
CREATE EXTERNAL SCHEMA [IF NOT EXISTS] local_schema_name
FROM [ [ DATA CATALOG ] | HIVE METASTORE | POSTGRES | MYSQL | KINESIS | MSK | REDSHIFT | KAFKA ]
[ DATABASE 'database_name' ]
[ SCHEMA 'schema_name' ]
[ REGION 'aws-region' ]
[ IAM_ROLE [ default | 'SESSION' | 'arn:aws:iam::<AWS 账户-id>:role/<role-name>' ] ]
[ AUTHENTICATION [ none | iam | mtls] ]
[ AUTHENTICATION_ARN 'acm-certificate-arn' | SECRET_ARN 'ssm-secret- arn' ]
[ URI ['hive_metastore_uri' [ PORT port_number ] | 'hostname' [ PORT port_number ] | 'Kafka bootstrap URL'] ] 
[ CLUSTER_ARN 'arn:aws:kafka:<region>:<AWS 账户-id>:cluster/msk/<cluster uuid>' ]
[ CATALOG_ROLE [ 'SESSION' | 'catalog-role-arn-string' ] ]
[ CREATE EXTERNAL DATABASE IF NOT EXISTS ]
[ CATALOG_ID 'Amazon Web Services account ID containing Glue or Lake Formation database' ]
```

以下语法描述了用于使用至 RDS POSTGRES 或 Aurora PostgreSQL 的联合查询引用数据的 CREATE EXTERNAL SCHEMA 命令。您还可以创建引用流式源的外部 Schema，例如 Kinesis Data Streams。有关更多信息，请参阅 [在 Amazon Redshift 中使用联合查询来查询数据](federated-overview.md)。

```
CREATE EXTERNAL SCHEMA [IF NOT EXISTS] local_schema_name
FROM POSTGRES
DATABASE 'federated_database_name' [SCHEMA 'schema_name']
URI 'hostname' [ PORT port_number ]
IAM_ROLE [ default | 'arn:aws:iam::<AWS 账户-id>:role/<role-name>' ]
SECRET_ARN 'ssm-secret-arn'
```

以下语法描述了用于使用至 RDS MySQL 或 Aurora MySQL 的联合查询引用数据的 CREATE EXTERNAL SCHEMA 命令。有关更多信息，请参阅 [在 Amazon Redshift 中使用联合查询来查询数据](federated-overview.md)。

```
CREATE EXTERNAL SCHEMA [IF NOT EXISTS] local_schema_name
FROM MYSQL
DATABASE 'federated_database_name'
URI 'hostname' [ PORT port_number ]
IAM_ROLE [ default | 'arn:aws:iam::<AWS 账户-id>:role/<role-name>' ]
SECRET_ARN 'ssm-secret-arn'
```

以下语法描述了用于引用 Kinesis 流中数据的 CREATE EXTERNAL SCHEMA 命令。有关更多信息，请参阅 [流式摄取到实体化视图](materialized-view-streaming-ingestion.md)。

```
CREATE EXTERNAL SCHEMA [IF NOT EXISTS] schema_name
FROM KINESIS
IAM_ROLE [ default | 'arn:aws:iam::<AWS 账户-id>:role/<role-name>' ]
```

以下语法描述了 CREATE EXTERNAL SCHEMA 命令，该命令用于引用 Amazon Managed Streaming for Apache Kafka 或 Confluent Cloud 集群及其要从中摄取的主题。要进行连接，您需要提供代理 URI。有关更多信息，请参阅 [流式摄取到实体化视图](materialized-view-streaming-ingestion.md)。

```
CREATE EXTERNAL SCHEMA [IF NOT EXISTS] schema_name
FROM KAFKA
[ IAM_ROLE [ default | 'arn:aws:iam::<AWS 账户-id>:role/<role-name>' ] ]
URI 'Kafka bootstrap URI'
AUTHENTICATION [ none | iam | mtls ]
[ AUTHENTICATION_ARN 'acm-certificate-arn' | SECRET_ARN 'ssm-secret- arn' ];
```

以下语法描述了用于使用跨 数据库查询引用数据的 CREATE EXTERNAL SCHEMA 命令。

```
CREATE EXTERNAL SCHEMA local_schema_name
FROM  REDSHIFT
DATABASE 'redshift_database_name' SCHEMA 'redshift_schema_name'
```

## 参数
<a name="r_CREATE_EXTERNAL_SCHEMA-parameters"></a>

IF NOT EXISTS  
一个子句，指示如果指定 schema 已存在，则此命令不应进行任何更改，并应返回一条指示 schema 存在的消息，而不是以错误终止。此子句在编写脚本时很有用，可使脚本在 CREATE EXTERNAL SCHEMA 尝试创建已存在的 schema 时不会失败。

local\$1schema\$1name  
新外部 schema 的名称。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。

FROM [ DATA CATALOG ] \$1 HIVE METASTORE \$1 POSTGRES \$1 MYSQL \$1 KINESIS \$1 MSK \$1 REDSHIFT   
指示外部数据库所在位置的关键词。  
DATA CATALOG 指示外部数据库是在 Athena 数据目录或 AWS Glue Data Catalog 中定义的。  
如果外部数据库是在位于其他 AWS 区域的外部 Data Catalog 中定义的，则 REGION 参数为必填项。DATA CATALOG 是默认值。  
HIVE METASTORE 指示外部数据库是在 Apache Hive 元存储中定义的。如果指定了 HIVE METASTORE，则 URI 为必填项。  
POSTGRES 指示外部数据库是在 RDS PostgreSQL 或 Aurora PostgreSQL 中定义的。  
MYSQL 表示外部数据库是在 RDS MySQL 或 Aurora MySQL 中定义的。  
KINESIS 指示数据来源是一个来自 Kinesis Data Streams 的流。  
MSK 表示数据来源是 Amazon MSK 预置的集群或无服务器集群。  
KAFKA 表示数据来源是 Kafka 集群。您可以对 Amazon MSK 和 Confluent Cloud 使用此关键词。

FROM REDSHIFT  
指示数据库位于 Amazon Redshift 中的关键词。

DATABASE“*redshift\$1database\$1name*”SCHEMA“*redshift\$1schema\$1name*”  
Amazon Redshift 数据库的名称。  
*redshift\$1schema\$1name* 指示 Amazon Redshift 中的 schema。默认的 *redshift\$1schema\$1name* 为 `public`。

数据库“federa*ted\$1database\$1name*”  
在支持的 PostgreSQL or MySQL 数据库引擎中指示外部数据库名称的关键词。

[SCHEMA '*schema\$1name*']  
*schema\$1name* 指示支持的 PostgreSQL 数据库引擎中的 schema。默认的 *schema\$1name* 是 `public`。  
在设置对受支持的 MySQL 数据库引擎的联合查询时，无法指定 SCHEMA。

REGION '*aws-region*'  
如果外部数据库是在 Athena 数据目录或 AWS Glue Data Catalog 中定义的，则为数据库所在的 AWS 区域。如果数据库是在外部 Data Catalog 中定义的，则此参数为必填项。

URI [ 'hive\$1metastore\$1uri' [ PORT port\$1number ] \$1 'hostname' [ PORT port\$1number ] \$1 'Kafka bootstrap URI' ]  
支持的 PostgreSQL 或 MySQL 数据库引擎的主机名 URI 和 port\$1number。*hostname* 是副本集的头节点。端点必须可以从 Amazon Redshift 集群进行访问（路由）。默认的 PostgreSQL port\$1number 为 5432。默认的 MySQL port\$1number 为 3306。  
支持的 PostgreSQL 或 MySQL 数据库引擎必须与 Amazon Redshift 集群位于同一个 VPC 中，而该集群的安全组将 Amazon Redshift 与 RDS url-rsPostgreSQL 或 Aurora PostgreSQL 相关联。此外，可以使用增强型 VPC 路由来配置跨 VPC 用例。有关更多信息，请参阅 [Redshift 托管的 VPC 端点](https://docs.aws.amazon.com/redshift/latest/mgmt/managing-cluster-cross-vpc.html)。
**指定 Hive 元存储 URI**  
如果数据库位于 Hive 元存储中，请指定 URI 并选择性地指定元存储的端口号。默认端口号为 9083。  
URI 不包含协议规范（“http://”）。有效 URI 示例：`uri '172.10.10.10'`。  
**指定用于流式摄取的代理 URI**  
包括引导代理 URI，即可连接到 Amazon MSK 或 Confluent Cloud 集群并接收流式传输数据。有关更多信息以及相关示例，请参阅[开始使用 Amazon Managed Streaming for Apache Kafka 流式摄取](https://docs.aws.amazon.com/redshift/latest/dg/materialized-view-streaming-ingestion-getting-started-MSK.html)。

IAM\$1ROLE [ default \$1 'SESSION' \$1 'arn:aws:iam::*<AWS 账户-id>*:role/*<role-name>*' ]  
使用默认关键字让 Amazon Redshift 使用设置为默认值并在 CREATE EXTERNAL SCHEMA 命令运行时与集群关联的 IAM 角色。  
如果您使用联合身份连接到 Amazon Redshift 集群并访问使用此命令创建的外部架构中的表，则使用 `'SESSION'`。有关更多信息，请参阅[使用联合身份管理 Amazon Redshift 对本地资源和 Amazon Redshift Spectrum 外部表的访问权限](https://docs.aws.amazon.com/redshift/latest/mgmt/authorization-fas-spectrum.html)，其中说明了如何配置联合身份。请注意，此配置（使用 `'SESSION'` 替代 ARN）仅在使用 `DATA CATALOG` 创建架构时才能使用。  
使用 IAM 角色的 Amazon 资源名称（ARN），您的集群使用该角色进行身份验证和授权。IAM 角色至少必须有权在要访问的 Amazon S3 桶上执行 LIST 操作和有权在该桶包含的 Amazon S3 对象上执行 GET 操作。  
下面显示了单个 ARN 的 IAM\$1ROLE 参数字符串的语法。  

```
IAM_ROLE 'arn:aws:iam::<aws-account-id>:role/<role-name>'
```
您可以将角色串联起来，以便集群可以承担另一个 IAM 角色 (可能属于其他账户)。您最多可串联 10 个角色。有关串联角色的示例，请参阅[在 Amazon Redshift Spectrum 中链接 IAM 角色](c-spectrum-iam-policies.md#c-spectrum-chaining-roles)。  
 对于此 IAM 角色，请附加类似于以下内容的 IAM 权限策略。    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AccessSecret",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetResourcePolicy",
                "secretsmanager:GetSecretValue",
                "secretsmanager:DescribeSecret",
                "secretsmanager:ListSecretVersionIds"
            ],
            "Resource": "arn:aws:secretsmanager:us-west-2:123456789012:secret:my-rds-secret-VNenFy"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetRandomPassword",
                "secretsmanager:ListSecrets"
            ],
            "Resource": "*"
        }
    ]
}
```
有关创建 IAM 角色以用于联合查询的步骤，请参阅[创建密钥和 IAM 角色以使用联合查询](federated-create-secret-iam-role.md)。  
请不要在链接的角色列表中包含空格。
下面显示了串联三个角色的语法。  

```
IAM_ROLE 'arn:aws:iam::<aws-account-id>:role/<role-1-name>,arn:aws:iam::<aws-account-id>:role/<role-2-name>,arn:aws:iam::<aws-account-id>:role/<role-3-name>'
```

SECRET\$1ARN '*ssm-secret-arn*'  
使用 AWS Secrets Manager 创建的支持的 PostgreSQL 或 MySQL 数据库引擎密钥的 Amazon 资源名称（ARN）。有关如何创建和检索密钥的 ARN 的信息，请参阅《AWS Secrets Manager User Guide》**中的 [Manage secrets with AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/manage_create-basic-secret.html)，以及[在 Amazon Redshift 中检索密钥的 Amazon 资源名称（ARN）](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-secrets-manager-integration-retrieving-secret.html)。

CATALOG\$1ROLE [ 'SESSION' \$1 *catalog-role-arn-string*]  
利用 `'SESSION'`，通过使用用于对数据目录进行身份验证和授权的联合身份来连接到 Amazon Redshift 集群。有关完成联合身份的步骤的更多信息，请参阅[使用联合身份管理 Amazon Redshift 对本地资源和 Amazon Redshift Spectrum 外部表的访问权限](https://docs.aws.amazon.com/redshift/latest/mgmt/authorization-fas-spectrum.html)。请注意，仅在 DATA CATALOG 中创建架构时才能使用 `'SESSION'` 角色。  
使用 IAM 角色的 Amazon 资源名称（ARN），您的集群使用该角色对数据目录进行身份验证和授权。  
如果未指定 CATALOG\$1ROLE，Amazon Redshift 会使用指定的 IAM\$1ROLE。目录角色必须有权限访问 AWS Glue 或 Athena 中的 Data Catalog。有关更多信息，请参阅 [适用于 Amazon Redshift Spectrum 的 IAM 策略](c-spectrum-iam-policies.md)。  
下面显示了单个 ARN 的 CATALOG\$1ROLE 参数字符串的语法。  

```
CATALOG_ROLE 'arn:aws:iam::<aws-account-id>:role/<catalog-role>'
```
您可以将角色串联起来，以便集群可以承担另一个 IAM 角色 (可能属于其他账户)。您最多可串联 10 个角色。有关更多信息，请参阅 [在 Amazon Redshift Spectrum 中链接 IAM 角色](c-spectrum-iam-policies.md#c-spectrum-chaining-roles)。  
串联角色的列表不能包含空格。
下面显示了串联三个角色的语法。  

```
CATALOG_ROLE 'arn:aws:iam::<aws-account-id>:role/<catalog-role-1-name>,arn:aws:iam::<aws-account-id>:role/<catalog-role-2-name>,arn:aws:iam::<aws-account-id>:role/<catalog-role-3-name>'
```


CREATE EXTERNAL DATABASE IF NOT EXISTS  
一个子句，用于在指定的外部数据库不存在时使用由 DATABASE 参数指定的名称创建外部数据库。如果指定的外部数据库存在，该命令不会进行任何更改。在这种情况下，该命令将返回指示外部数据库存在的消息，而不是以错误终止。  
CREATE EXTERNAL DATABASE IF NOT EXISTS 不能与 HIVE METASTORE 一起使用。  
要将 CREATE EXTERNAL DATABASE IF NOT EXISTS 与为 AWS Lake Formation 启用的 Data Catalog 搭配使用，需要获得对于 Data Catalog 的 `CREATE_DATABASE` 权限。

CATALOG\$1ID '*Amazon Web Services 账户 ID，包含 Glue 或 Lake Formation 数据库*'  
用于存储数据目录数据库的账户 ID。  
只有在您计划使用联合身份（用于对数据目录进行身份验证和授权）连接到 Amazon Redshift 集群或 Amazon Redshift Serverless 时，才能通过设置以下任一项来指定 `CATALOG_ID`：  
+ `CATALOG_ROLE`到 `'SESSION'`。
+ 将 `IAM_ROLE` 设置为 `'SESSION'`，并将 `'CATALOG_ROLE'` 设置为默认值 
有关完成联合身份的步骤的更多信息，请参阅[使用联合身份管理 Amazon Redshift 对本地资源和 Amazon Redshift Spectrum 外部表的访问权限](https://docs.aws.amazon.com/redshift/latest/mgmt/authorization-fas-spectrum.html)。

AUTHENTICATION  
为流式摄取定义的身份验证类型。具有身份验证类型的流式摄取使用 Amazon Managed Streaming for Apache Kafka。`AUTHENTICATION` 类型为：  
+ **无** – 指定不需要身份验证。这对应于 MSK 上未经身份验证的访问，或者 Apache Kafka 上具有 TLS 的纯文本。
+ **iam** – 指定 IAM 身份验证。选择此选项时，请确保 IAM 角色具有 IAM 身份验证的权限。有关定义外部模式的更多信息，请参阅[从 Apache Kafka 源进行流式摄取入门](materialized-view-streaming-ingestion-getting-started-MSK.md)。
+ **mtls** – 指定双向传输层安全通过促进客户端和服务器之间的身份验证来提供安全通信。在本例中，客户端是 Redshift，服务器是 Amazon MSK。有关使用 mTLS 配置流式摄取的更多信息，请参阅 [使用 mTLS 对来自 Apache Kafka 源的 Redshift 流式摄取进行身份验证](materialized-view-streaming-ingestion-mtls.md)。


AUTHENTICATION\$1ARN  
Amazon Redshift 用于通过 Amazon MSK 进行 mtls 身份验证的 AWS Certificate Manager 证书的 ARN。当您选择已签发证书时，ARN 就会出现在 ACM 控制台中。

CLUSTER\$1ARN  
对于流式摄取，CLUSTER\$1ARN 是您从中进行流式传输的 Amazon Managed Streaming for Apache Kafka 集群的集群标识符。使用 CLUSTER\$1ARN 时，它需要包含 `kafka:GetBootstrapBrokers` 权限的 IAM 角色策略。此选项是为了向后兼容性而提供的。目前，我们建议使用引导代理 URI 选项连接到 Amazon Managed Streaming for Apache Kafka 集群。有关更多信息，请参阅[流式摄取](https://docs.aws.amazon.com/redshift/latest/dg/materialized-view-streaming-ingestion.html)。

## 使用说明
<a name="r_CREATE_EXTERNAL_SCHEMA_usage"></a>

有关使用 Athena 数据目录时的限制，请参阅《AWS 一般参考》中的 [Athena 限制](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#amazon-athena-limits)。

有关使用 AWS Glue Data Catalog 时的限制，请参阅《AWS 一般参考》中的 [AWS Glue 限制](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#limits_glue)。

这些限制不适用于 Hive 元存储。

每个数据库最多有 9900 个架构。有关更多信息，请参阅《Amazon Redshift 管理指南》**中的[配额和限制](https://docs.aws.amazon.com/redshift/latest/mgmt/amazon-redshift-limits.html)。

要取消注册架构，请使用 [DROP SCHEMA](r_DROP_SCHEMA.md) 命令。

要查看外部架构的详细信息，请查询以下系统视图：
+ [SVV\$1EXTERNAL\$1SCHEMAS](r_SVV_EXTERNAL_SCHEMAS.md) 
+ [SVV\$1EXTERNAL\$1TABLES](r_SVV_EXTERNAL_TABLES.md) 
+ [SVV\$1EXTERNAL\$1COLUMNS](r_SVV_EXTERNAL_COLUMNS.md) 

## 示例
<a name="r_CREATE_EXTERNAL_SCHEMA_examples"></a>

以下示例使用位于美国西部（俄勒冈州）区域的名为 `sampledb` 的数据目录中的数据库，创建一个外部模式。将此示例与 Athena 或 AWS Glue 数据目录结合使用。

```
create external schema spectrum_schema
from data catalog
database 'sampledb'
region 'us-west-2'
iam_role 'arn:aws:iam::123456789012:role/MySpectrumRole';
```

以下示例创建一个外部 schema 并新建一个名为 `spectrum_db` 的新外部数据库。

```
create external schema spectrum_schema
from data catalog
database 'spectrum_db'
iam_role 'arn:aws:iam::123456789012:role/MySpectrumRole'
create external database if not exists;
```

以下示例创建一个使用名为 `hive_db` 的 Hive 元存储数据库的外部 schema。

```
create external schema hive_schema
from hive metastore
database 'hive_db'
uri '172.10.10.10' port 99
iam_role 'arn:aws:iam::123456789012:role/MySpectrumRole';
```

以下示例将角色串联起来，以使用角色 `myS3Role` 来访问 Amazon S3 ，并且使用 `myAthenaRole` 进行数据目录访问。有关更多信息，请参阅 [在 Amazon Redshift Spectrum 中链接 IAM 角色](c-spectrum-iam-policies.md#c-spectrum-chaining-roles)。

```
create external schema spectrum_schema
from data catalog
database 'spectrum_db'
iam_role 'arn:aws:iam::123456789012:role/myRedshiftRole,arn:aws:iam::123456789012:role/myS3Role'
catalog_role 'arn:aws:iam::123456789012:role/myAthenaRole'
create external database if not exists;
```

以下示例创建引用 Aurora PostgreSQL 数据库的外部 schema。

```
CREATE EXTERNAL SCHEMA [IF NOT EXISTS] myRedshiftSchema
FROM POSTGRES
DATABASE 'my_aurora_db' SCHEMA 'my_aurora_schema'
URI 'endpoint to aurora hostname' PORT 5432  
IAM_ROLE 'arn:aws:iam::123456789012:role/MyAuroraRole'
SECRET_ARN 'arn:aws:secretsmanager:us-east-2:123456789012:secret:development/MyTestDatabase-AbCdEf'
```

以下示例创建一个外部架构来引用导入到使用者集群上的 sales\$1db。

```
CREATE EXTERNAL SCHEMA sales_schema FROM REDSHIFT DATABASE 'sales_db' SCHEMA 'public';
```

以下示例创建引用 Aurora MySQL 数据库的外部 schema。

```
CREATE EXTERNAL SCHEMA [IF NOT EXISTS] myRedshiftSchema
FROM MYSQL
DATABASE 'my_aurora_db'
URI 'endpoint to aurora hostname'
IAM_ROLE 'arn:aws:iam::123456789012:role/MyAuroraRole'
SECRET_ARN 'arn:aws:secretsmanager:us-east-2:123456789012:secret:development/MyTestDatabase-AbCdEf'
```

# CREATE EXTERNAL TABLE
<a name="r_CREATE_EXTERNAL_TABLE"></a>

在指定 schema 中创建一个新外部表。所有外部表必须在外部 schema 中创建。外部 schema 和外部表不支持搜索路径。有关更多信息，请参阅 [CREATE EXTERNAL SCHEMA](r_CREATE_EXTERNAL_SCHEMA.md)。

除了使用 CREATE EXTERNAL TABLE 命令创建的外部表之外，Amazon Redshift 还可引用在 AWS Glue 或 AWS Lake Formation 目录或 Apache Hive 元存储中定义的外部表。使用 [CREATE EXTERNAL SCHEMA](r_CREATE_EXTERNAL_SCHEMA.md) 命令可注册在外部目录中定义的外部数据库并使外部表可在 Amazon Redshift 中使用。如果外部表已存在于 AWS Glue 或 AWS Lake Formation 目录或 Hive 元存储中，您无需使用 CREATE EXTERNAL TABLE 创建该表。要查看外部表，请查询 [SVV\$1EXTERNAL\$1TABLES](r_SVV_EXTERNAL_TABLES.md) 系统视图。

通过运行 CREATE EXTERNAL TABLE AS 命令，可以根据查询中的列定义创建外部表，并将该查询的结果写入 Amazon S3 中。结果采用 Apache Parquet 或分隔的文本格式。如果外部表具有一个或多个分区键，Amazon Redshift 会根据这些分区键对新文件进行分区，并自动将新分区注册到外部目录中。有关 CREATE EXTERNAL TABLE AS 的更多信息，请参阅[使用说明](r_CREATE_EXTERNAL_TABLE_usage.md)。

您可使用用于其他 Amazon Redshift 表的同一 SELECT 语法查询外部表。您还可以使用 INSERT 语法将新文件写入 Amazon S3 上外部表的位置。有关更多信息，请参阅 [INSERT（外部表）](r_INSERT_external_table.md)。

要使用外部表创建视图，请在 [CREATE VIEW](r_CREATE_VIEW.md) 语句中包含 WITH NO SCHEMA BINDING 子句。

您无法在事务 (BEGIN … END) 内运行 CREATE EXTERNAL TABLE。有关事务的更多信息，请参阅 [Amazon Redshift 中的隔离级别](c_serial_isolation.md)。

## 所需的权限
<a name="r_CREATE_EXTERNAL_TABLE-privileges"></a>

要创建外部表，您必须是外部 schema 的所有者或是超级用户。要移交外部 schema 的所有权，请使用 ALTER SCHEMA 更改所有者。对外部表的访问由对外部 schema 的访问权限控制。您无法对外部表的权限执行 [GRANT](r_GRANT.md) 或 [REVOKE](r_REVOKE.md) 操作。但是，您可授予或撤销对外部 schema 的 USAGE 权限。

[使用说明](r_CREATE_EXTERNAL_TABLE_usage.md) 包含有关外部表特定权限的更多信息。

## 语法
<a name="r_CREATE_EXTERNAL_TABLE-synopsis"></a>

```
CREATE EXTERNAL TABLE
external_schema.table_name
(column_name data_type [, …] )
[ PARTITIONED BY (col_name data_type [, … ] )]
[ { ROW FORMAT DELIMITED row_format |
  ROW FORMAT SERDE 'serde_name'
  [ WITH SERDEPROPERTIES ( 'property_name' = 'property_value' [, ...] ) ] } ]
STORED AS file_format
LOCATION { 's3://bucket/folder/' | 's3://bucket/manifest_file' }
[ TABLE PROPERTIES ( 'property_name'='property_value' [, ...] ) ]
```

以下是 CREATE EXTERNAL TABLE AS 的语法。

```
CREATE EXTERNAL TABLE
external_schema.table_name
[ PARTITIONED BY (col_name [, … ] ) ]
[ ROW FORMAT DELIMITED row_format ]
STORED AS file_format
LOCATION { 's3://bucket/folder/' }
[ TABLE PROPERTIES ( 'property_name'='property_value' [, ...] ) ]
 AS
 { select_statement }
```

## 参数
<a name="r_CREATE_EXTERNAL_TABLE-parameters"></a>

 *external\$1schema.table\$1name*   
要创建的表的名称（由外部 schema 名称进行限定）。外部表必须在外部 schema 中创建。有关更多信息，请参阅 [CREATE EXTERNAL SCHEMA](r_CREATE_EXTERNAL_SCHEMA.md)。  
表名称的最大长度为 127 个字节；更长的名称将被截断为 127 个字节。您可以使用 UTF-8 多字节字符，每个字符最多为四个字节。Amazon Redshift 对每个集群强制实施 9900 个表的限制，包括用户定义的临时表以及查询处理或系统维护期间由 Amazon Redshift 创建的临时表。您也可以使用数据库名称限定表名称。在下面的示例中，`spectrum_db` 是数据库名称，`spectrum_schema` 是外部 schema 名称，而 `test` 是表名称。  

```
create external table spectrum_db.spectrum_schema.test (c1 int)
stored as parquet
location 's3://amzn-s3-demo-bucket/myfolder/';
```
如果指定数据库或 schema 不存在，则不会创建表，并且语句将返回错误。您无法在系统数据库 `template0`、`template1`、`padb_harvest` 或 `sys:internal` 中创建表或视图。  
表名称对于指定 schema 必须是唯一名称。  
有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。

( *column\$1name* *data\$1type* )  
要创建的每个列的名称和数据类型。  
列名称的最大长度为 127 个字节；更长的名称将被截断为 127 个字节。您可以使用 UTF-8 多字节字符，每个字符最多为四个字节。不能指定列名称 `"$path"` 或 `"$size"`。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。  
预设情况下，Amazon Redshift 使用伪列 `$path` 和 `$size` 创建外部表。您可以通过将 `spectrum_enable_pseudo_columns` 配置参数设置为 `false` 来禁用为会话创建 pseudocolumns 的功能。有关更多信息，请参阅 [Pseudocolumns](r_CREATE_EXTERNAL_TABLE_usage.md#r_CREATE_EXTERNAL_TABLE_usage-pseudocolumns)。  
如果已启用 pseudocolumns，则可在单个表中定义的最大列数为 1598。如果未启用 pseudocolumns，则可在单个表中定义的最大列数为 1600。  
如果您创建的是“宽表”，请确保在加载和查询处理期间，不要让列列表超出中间结果的行宽度边界。有关更多信息，请参阅 [使用说明](r_CREATE_TABLE_NEW.md#r_CREATE_TABLE_usage)。  
对于 CREATE EXTERNAL TABLE AS 命令，不需要列的列表，因为列是从查询派生的。

 *data\$1type*   
支持以下[数据类型](c_Supported_data_types.md)：  
+ SMALLINT (INT2)
+ INTEGER (INT, INT4)
+ BIGINT (INT8)
+ DECIMAL (NUMERIC)
+ REAL (FLOAT4)
+ DOUBLE PRECISION (FLOAT8)
+ BOOLEAN (BOOL)
+ CHAR (CHARACTER)
+ VARCHAR (CHARACTER VARYING)
+ VARBYTE (CHARACTER VARYING) – 可与 Parquet 和 ORC 数据文件一起使用，并且只能用于非分区表。
+ DATE – 只能与文本、Parquet 或 ORC 数据文件一起使用，或者用作分区列。
+ TIMESTAMP
  
对于 DATE，您可以使用以下所示的格式。对于使用数字表示的月份值，支持以下格式：  
+ `mm-dd-yyyy` - 例如：`05-01-2017`这是默认模式。
+ `yyyy-mm-dd`，其中年份由 2 位以上的数字表示。例如 `2017-05-01`。
对于使用三个字母缩写表示的月份值，则支持以下格式：  
+ `mmm-dd-yyyy` - 例如：`may-01-2017`这是默认模式。
+ `dd-mmm-yyyy`，其中年份由 2 位以上的数字表示。例如 `01-may-2017`。
+ `yyyy-mmm-dd`，其中年份由 2 位以上的数字表示。例如 `2017-may-01`。
对于始终小于 100 的年份值，请按以下方式计算年份：  
+ 如果年份值小于 70，则在计算年份时加上 2000。例如，以 `mm-dd-yyyy` 格式表示的日期 05-01-17 将被转换为 `05-01-2017`。
+ 如果年份值小于 100 但大于 69，则在计算年份时加上 1900。例如，以 `mm-dd-yyyy` 格式表示的日期 05-01-89 将被转换为 `05-01-1989`。
+ 对于以两位数表示的年份值，请添加前导零，以 4 位数表示年份。
文本文件中的时间戳值的格式必须为 `yyyy-mm-dd HH:mm:ss.SSSSSS`，如以下时间戳值所示：`2017-05-01 11:30:59.000000`。  
VARCHAR 列的长度的定义单位是字节而不是字符。例如，VARCHAR(12) 列可包含 12 个单字节字符或 6 个双字节字符。查询外部表时，将截断结果以适合定义的列大小，而不返回错误。有关更多信息，请参阅 [存储和范围](r_Character_types.md#r_Character_types-storage-and-ranges)。  
为获得最佳性能，我们建议您指定适合您数据的最小列大小。要查找列中值的最大大小（以字节为单位），请使用 [OCTET\$1LENGTH](r_OCTET_LENGTH.md) 函数。以下示例返回电子邮件列中值的大小上限。  

```
select max(octet_length(email)) from users;

max
---
 62
```

PARTITIONED BY (*col\$1name* *data\$1type* [, … ] )  
用于定义包含一个或多个分区列的已分区表的子句。单独的数据目录用于每个指定的组合，这在某些情况下可提高查询性能。已分区列在表数据本身中不存在。如果您将与表列相同的某个值用于 *col\$1name*，则会产生错误。  
创建分区表后，使用 [ALTER TABLE](r_ALTER_TABLE.md) … ADD PARTITION 语句更改表，以将新分区注册到外部目录。在添加分区时，您应定义包含分区数据的子文件夹在 Amazon S3 上的位置。  
例如，如果表 `spectrum.lineitem_part` 是使用 `PARTITIONED BY (l_shipdate date)` 定义的，请运行以下 ALTER TABLE 命令来添加分区。  

```
ALTER TABLE spectrum.lineitem_part ADD PARTITION (l_shipdate='1992-01-29')
LOCATION 's3://spectrum-public/lineitem_partition/l_shipdate=1992-01-29';
```
如果您使用 CREATE EXTERNAL TABLE AS，则不需要运行 ALTER TABLE...ADD PARTITION。Amazon Redshift 会自动在外部目录中注册新分区。Amazon Redshift 还会根据表中定义的一个或多个分区键自动将相应的数据写入 Amazon S3 中的分区。  
要查看分区，请查询 [SVV\$1EXTERNAL\$1PARTITIONS](r_SVV_EXTERNAL_PARTITIONS.md) 系统视图。  
对于 CREATE EXTERNAL TABLE AS 命令，您不需要指定分区列的数据类型，因为此列是从查询派生的。

ROW FORMAT DELIMITED *rowformat*  
用于指定基础数据的格式的子句。*rowformat* 的可能值如下所示：  
+ LINES TERMINATED BY '*delimiter*'
+ FIELDS TERMINATED BY '*delimiter*'
为 '*delimiter*' 指定一个 ASCII 字符。您可以指定使用八进制格式的非打印 ASCII 字符，具体格式为 `'\`*`ddd`*`'`，其中 *`d`* 是一个八进制数（0–7），最大为“\$1177”。以下示例使用八进制形式指定 BEL（响铃）字符。  

```
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\007'
```
如果省略了 ROW FORMAT，则默认格式为 DELIMITED FIELDS TERMINATED BY '\$1A'（标题开头）和 LINES TERMINATED BY '\$1n'（换行符）。

ROW FORMAT SERDE '*serde\$1name*'[WITH SERDEPROPERTIES ( '*property\$1name*' = '*property\$1value*' [, ...] ) ]  
用于为基础数据指定 SERDE 格式的子句。    
'*serde\$1name*'  
SerDe 的名称。您可以指定以下格式：  
+ org.apache.hadoop.hive.serde2.RegexSerDe 
+ com.amazonaws.glue.serde.GrokSerDe 
+ org.apache.hadoop.hive.serde2.OpenCSVSerde 

  此参数支持 OpenCSVSerde 的以下 SerDe 属性：

  ```
  'wholeFile' = 'true' 
  ```

  将 `wholeFile` 属性设置为 `true`，以正确解析 OpenCSV 请求的引号字符串中的新行字符 (\$1n)。
+ org.openx.data.jsonserde.JsonSerDe
  + JSON SERDE 还支持 Ion 文件。
  + JSON 必须格式正确。
  + Ion 和 JSON 中的时间戳必须使用 ISO8601 格式。
  + 该参数支持 JsonSerDe 的以下 SerDe 属性：

    ```
    'strip.outer.array'='true' 
    ```

    处理 Ion/JSON 文件，其中包含一个包含在方括号 ( [ … ] ) 中的非常大的数组，就像它在数组中包含多个 JSON 记录一样。
+ com.amazon.ionhiveserde.IonHiveSerDe

  除数据类型外，Amazon ION 格式还提供文本和二进制格式。对于引用 ION 格式数据的外部表，将外部表中的每个列映射到 ION 格式数据中的对应元素。有关更多信息，请参阅 [Amazon Ion](https://amzn.github.io/ion-docs/)。此外，您还需要指定输入和输出格式。  
WITH SERDEPROPERTIES ( '*property\$1name*' = '*property\$1value*' [, ...] ) ]  
（可选）指定以逗号分隔的属性名称和值。
如果省略了 ROW FORMAT，则默认格式为 DELIMITED FIELDS TERMINATED BY '\$1A'（标题开头）和 LINES TERMINATED BY '\$1n'（换行符）。

STORED AS *file\$1format*  
数据文件的文件格式。  
有效格式如下所示：  
+ PARQUET
+ RCFILE (仅针对使用 ColumnarSerDe 而不是 LazyBinaryColumnarSerDe 的数据)
+ SEQUENCEFILE
+ TEXTFILE（针对文本文件，包括 JSON 文件）。
+ ORC 
+ AVRO 
+ INPUTFORMAT '*input\$1format\$1classname*' OUTPUTFORMAT '*output\$1format\$1classname*'
CREATE EXTERNAL TABLE AS 命令只支持两种文件格式：TEXTFILE 和 PARQUET。  
对于 INPUTFORMAT 和 OUTPUTFORMAT，指定类名称，如下例所示。  

```
'org.apache.hadoop.mapred.TextInputFormat'
```

LOCATION \$1 's3://*bucket/folder*/' \$1 's3://*bucket/manifest\$1file*'\$1  <a name="create-external-table-location"></a>
包含数据文件的 Amazon S3 桶或文件夹的路径或包含 Amazon S3 对象路径列表的清单文件。桶必须与 Amazon Redshift 集群位于同一 AWS 区域。有关受支持的 AWS 区域的列表，请参阅[Amazon Redshift Spectrum 限制](c-spectrum-considerations.md)。  
如果路径指定桶或文件夹，例如 `'s3://amzn-s3-demo-bucket/custdata/'`，Redshift Spectrum 会扫描指定的桶或文件夹和任意子文件夹中的文件。Redshift Spectrum 将忽略隐藏文件和以句点或下划线开头的文件。  
如果路径指定清单文件，则 `'s3://bucket/manifest_file'` 参数必须显式引用单个文件，例如 `'s3://amzn-s3-demo-bucket/manifest.txt'`。它不能引用键前缀。  
清单是 JSON 格式的文本文件，其中列出了要从 Amazon S3 加载的每个文件的 URL 以及文件的大小（以字节为单位）。URL 包含文件的桶名称和完整对象路径。在清单中指定的文件可以位于不同的桶中，但所有桶都必须位于 Amazon Redshift 集群所在的同一 AWS 区域。如果某个文件被列出两次，那么该文件也会被加载两次。以下示例显示了加载三个文件的清单的 JSON。  

```
{
  "entries": [
    {"url":"s3://amzn-s3-demo-bucket1/custdata.1", "meta": { "content_length": 5956875 } },
    {"url":"s3://amzn-s3-demo-bucket1/custdata.2", "meta": { "content_length": 5997091 } },
    {"url":"s3://amzn-s3-demo-bucket2/custdata.1", "meta": { "content_length": 5978675 } }
  ]
}
```
您可以强制包含特定文件。为此，请在清单中的文件级别包含一个 `mandatory` 选项。当您查询缺少强制性文件的外部表时，SELECT 语句将失败。确保外部表定义中包含的所有文件都存在。如果它们并非全部存在，则会显示一个错误，显示未找到的第一个强制性文件。以下示例显示 `mandatory` 选项设置为 `true` 的清单的 JSON。  

```
{
  "entries": [
    {"url":"s3://amzn-s3-demo-bucket1/custdata.1", "mandatory":true, "meta": { "content_length": 5956875 } },
    {"url":"s3://amzn-s3-demo-bucket1/custdata.2", "mandatory":false, "meta": { "content_length": 5997091 } },
    {"url":"s3://amzn-s3-demo-bucket2/custdata.1", "meta": { "content_length": 5978675 } }
  ]
}
```
要引用使用 UNLOAD 创建的文件，您可以使用通过 [UNLOAD](r_UNLOAD.md) 和 MANIFEST 参数创建的清单。该清单文件与 [从 Amazon S3 执行 COPY 操作](copy-parameters-data-source-s3.md) 的清单文件兼容，但使用不同的密钥。不使用的密钥会被忽略。

TABLE PROPERTIES ( '*property\$1name*'='*property\$1value*' [, ...] )   
用于设置表属性的表定义的子句。  
表属性区分大小写。  
 'compression\$1type'='*value*'  
 一个属性，它在文件名不包含扩展名时设置要使用的压缩类型。如果您设置此属性且存在文件扩展名，则将忽略该扩展名，并使用由此属性设置的值。压缩类型的有效值如下：  
+ bzip2
+ gzip
+ 无
+ snappy  
'data\$1cleansing\$1enabled'='true / false’  
该属性设置该表的数据处理是否已启用。当“data\$1cleansing\$1enabled”设置为 true 时，表的数据处理将启用。当“data\$1cleansing\$1enabled”设置为 false 时，表的数据处理将关闭。以下是由此属性控制的表级别数据处理属性的列表：  
+ column\$1count\$1mismatch\$1handling
+ invalid\$1char\$1handling
+ numeric\$1overflow\$1handling
+ replacement\$1char
+ surplus\$1char\$1handling
有关示例，请参阅 [数据处理示例](r_CREATE_EXTERNAL_TABLE_examples.md#r_CREATE_EXTERNAL_TABLE_examples-data-handling)。  
'invalid\$1char\$1handling'='*value*'  
指定当查询结果包含无效的 UTF-8 字符值时要执行的操作。您可以指定以下操作：    
DISABLED  
不执行无效字符处理。  
FAIL  
取消返回包含无效 UTF-8 值的数据的查询。  
SET\$1TO\$1NULL   
将无效 UTF-8 值替换为 null。  
DROP\$1ROW  
将行中的每个值替换为 null。  
REPLACE  
使用 `replacement_char`，将无效字符替换为您指定的替换字符。  
'replacement\$1char'='*character*’  
当您将 `invalid_char_handling` 设置为 `REPLACE` 时，请指定要使用的替换字符。  
'numeric\$1overflow\$1handling'='value’  
指定 ORC 数据包含大于列定义（例如，SMALLINT 或 int16）的整数（例如，BIGINT 或 int64）时要执行的操作。您可以指定以下操作：    
DISABLED  
关闭无效字符处理。  
FAIL  
当数据包含无效字符时取消查询。  
SET\$1TO\$1NULL  
将无效字符设置为 null。  
DROP\$1ROW  
将行中的每个值设置为 null。  
'surplus\$1bytes\$1handling'='*value*'  
指定如何处理加载的数据，其长度超过为包含 VARBYTE 数据的列所定义的数据类型的长度。默认情况下，对于超出列宽度的数据，Redshift Spectrum 会将该值设置为 null。  
当查询返回超过数据类型长度的数据时，您可以指定以下要执行的操作：    
SET\$1TO\$1NULL  
将超过列宽度的数据替换为 null。  
DISABLED  
不执行超额字节处理。  
FAIL  
取消返回超过列宽度的数据的查询。  
DROP\$1ROW  
剔除包含超过列宽度的数据的所有行。  
TRUNCATE  
移除超出列定义的最大字符数的字符。  
'surplus\$1char\$1handling'='*value*'  
指定如何处理加载的数据，其长度超过包含 VARCHAR、CHAR 或字符串数据列所定义的数据类型长度。默认情况下，对于超出列宽度的数据，Redshift Spectrum 会将该值设置为 null。  
当查询返回超过列宽的数据时，您可以指定以下要执行的操作：    
SET\$1TO\$1NULL  
将超过列宽度的数据替换为 null。  
DISABLED  
不执行超额字符处理。  
FAIL  
取消返回超过列宽度的数据的查询。  
DROP\$1ROW  
将行中的每个值替换为 null。  
TRUNCATE  
移除超出列定义的最大字符数的字符。  
'column\$1count\$1mismatch\$1handling'='value’  
确定文件包含的行值是否小于或大于外部表定义中指定的列数。此属性仅适用于未压缩的文本文件格式。您可以指定以下操作：    
DISABLED  
列计数不匹配处理处于关闭状态。  
FAIL  
如果检测到列计数不匹配，则查询失败。  
SET\$1TO\$1NULL  
使用 NULL 填充缺失值并忽略每行中的其他值。  
DROP\$1ROW  
剔除包含扫描中列计数不匹配错误的所有行。  
'numRows'='*row\$1count*'  
用于为表定义设置 numRows 值的属性。若要显式更新外部表的统计数据，请设置 numRows 属性来指示表的大小。Amazon Redshift 不分析外部表来生成表统计数据，查询优化程序会使用这些统计数据来生成查询计划。如果没有为外部表设置表统计数据，则 Amazon Redshift 假设外部表是较大的表，本地表是较小的表，以此来生成查询执行计划。  
'skip.header.line.count'='*line\$1count*'  
用于设置在每个源文件开头要跳过的行数的属性。  
'serialization.null.format'=' '  
一个属性，指定当存在与某个字段中提供的文本完全匹配的项时，Spectrum 应返回 `NULL` 值。  
'orc.schema.resolution'='mapping\$1type'  
一个属性，用于设置使用 ORC 数据格式的表的列映射类型。其他数据格式将忽略此属性。  
列映射类型的有效值如下：  
+ 名称 
+ position 
如果省略 *orc.schema.resolution* 属性，默认情况下会按名称映射列。如果将 *orc.schema.resolution* 设置为*“name”*或*“position”*之外的任何其他值，则按位置映射列。有关列映射的更多信息，请参阅[将外部表列映射到 ORC 列](c-spectrum-external-tables.md#c-spectrum-column-mapping-orc)。  
COPY 命令仅按位置映射到 ORC 数据文件。*orc.schema.resolution* 表属性对 COPY 命令行为无效。  
'write.parallel'='on / off’  
一个属性，用于设置是否 CREATE EXTERNAL TABLE AS 应并行写入数据。默认情况下，CREATE EXTERNAL TABLE AS 根据集群中的切片数量将数据并行写入到多个文件。默认选项为打开。当“write.parallel”设置为关闭时，CREATE EXTERNAL TABLE AS 以串行方式将一个或多个数据文件写入到 Amazon S3。该表属性还适用于指向同一外部表的所有后续 INSERT 语句。  
‘write.maxfilesize.mb’=‘size’  
设置由 CREATE EXTERNAL TABLE AS 写入到 Amazon S3 中的每个文件的最大大小（以 MB 为单位）的属性。大小必须是介于 5 到 6200 之间的有效整数。默认最大文件大小为 6,200 MB。该表属性还适用于指向同一外部表的所有后续 INSERT 语句。  
‘write.kms.key.id’=‘*value*’  
您可以指定一个 AWS Key Management Service 密钥，为 Amazon S3 对象启用服务器端加密 (SSE)，其中 *value* 为以下值之一：  
+ `auto`，使用存储在 Amazon S3 桶中的默认 AWS KMS 密钥。
+ *kms-key*，用于指定加密数据。  
*select\$1statement*  
通过定义任何查询将一行或多行插入外部表的语句。查询生成的所有行都将根据表定义以文本或 Parquet 格式写入到 Amazon S3。

## 示例
<a name="r_CREATE_EXTERNAL_TABLE_examples_link"></a>

[示例](r_CREATE_EXTERNAL_TABLE_examples.md) 中提供了一系列示例。

# 使用说明
<a name="r_CREATE_EXTERNAL_TABLE_usage"></a>

本主题包含 [CREATE EXTERNAL TABLE](r_CREATE_EXTERNAL_TABLE.md) 的用法说明。您无法使用用于标准 Amazon Redshift 表（如 [PG\$1TABLE\$1DEF](r_PG_TABLE_DEF.md)、[STV\$1TBL\$1PERM](r_STV_TBL_PERM.md)、PG\$1CLASS 或 information\$1schema）的同一资源查看 Amazon Redshift Spectrum 表的详细信息。如果您的商业智能或分析工具无法识别 Redshift Spectrum 外部表，请将您的应用程序为配置查询 [SVV\$1EXTERNAL\$1TABLES](r_SVV_EXTERNAL_TABLES.md) 和 [SVV\$1EXTERNAL\$1COLUMNS](r_SVV_EXTERNAL_COLUMNS.md)。

## CREATE EXTERNAL TABLE AS
<a name="r_CETAS"></a>

在某些情况下，您可能会对 AWS Glue Data Catalog、AWS Lake Formation 外部目录或 Apache Hive 元存储运行 CREATE EXTERNAL TABLE AS 命令。在这种情况下，您使用 AWS Identity and Access Management (IAM) 角色创建外部架构。此 IAM 角色必须同时具有在 Amazon S3 上读取和写入的权限。

如果您使用 Lake Formation 目录，则 IAM 角色必须具有在目录中创建表的权限。在这种情况下，它还必须对目标 Amazon S3 路径具有数据湖位置权限。此 IAM 角色成为新 AWS Lake Formation 表的所有者。

为确保文件名是唯一的，Amazon Redshift 预设情况下对上载到 Amazon S3 的每个文件的名称使用以下格式。

`<date>_<time>_<microseconds>_<query_id>_<slice-number>_part_<part-number>.<format>`.

 示例是 `20200303_004509_810669_1007_0001_part_00.parquet`。

运行 CREATE EXTERNAL TABLE AS 命令时，请考虑以下事项：
+ Amazon S3 位置必须为空。
+ Amazon Redshift 仅在使用 STORED AS 子句时才支持 PARQUET 和 TEXTFILE 格式。
+ 您不需要定义列定义列表。新外部表的列名和列数据类型直接从 SELECT 查询获得。
+ 您无需在 PARTITIONED BY 子句中定义分区列的数据类型。如果指定分区键，则此列的名称必须存在于 SELECT 查询结果中。当有多个分区列时，它们在 SELECT 查询中的顺序并不重要。Amazon Redshift 使用在 PARTITIONED BY 子句中定义的顺序来创建外部表。
+ Amazon Redshift 根据分区键值自动将输出文件分区到分区文件夹中。预设情况下，Amazon Redshift 从输出文件中删除分区列。
+ 不支持 LINES TERMINATED BY 'delimiter' 子句。
+ 不支持 ROW FORMAT SERDE 'serde\$1name' 子句。
+ 不支持使用清单文件。因此，您无法在 Amazon S3 上的清单文件中定义 LOCATION 子句。
+ Amazon Redshift 自动在命令末尾更新“numRows”表属性。
+ 'compression\$1type' 表属性对于 PARQUET 文件格式仅接受 'none' 或 'snappy'。
+ Amazon Redshift 不允许在外部 SELECT 查询中使用 LIMIT 子句。相反，您可以使用嵌套的 LIMIT 子句。
+ 您可以使用 STL\$1UNLOAD\$1LOG 跟踪由每个 CREATE EXTERNAL TABLE AS 操作写入到 Amazon S3 的文件。

## 创建和查询外部表的权限
<a name="r_CREATE_EXTERNAL_TABLE_usage-permissions"></a>

要创建外部表，请确保您是外部架构的所有者或超级用户。要移交外部 schema 的所有权，请使用 [ALTER SCHEMA](r_ALTER_SCHEMA.md)。以下示例将 `spectrum_schema` schema 的所有者更改为 `newowner`。

```
alter schema spectrum_schema owner to newowner;
```

要运行 Redshift Spectrum 查询，您需要以下权限：
+ schema 的使用权限 
+ 在当前数据库中创建临时表的权限 

以下示例将 schema `spectrum_schema` 的使用权限授予 `spectrumusers` 用户组。

```
grant usage on schema spectrum_schema to group spectrumusers;
```

以下示例将数据库 `spectrumdb` 的临时权限授予 `spectrumusers` 用户组。

```
grant temp on database spectrumdb to group spectrumusers;
```

## Pseudocolumns
<a name="r_CREATE_EXTERNAL_TABLE_usage-pseudocolumns"></a>

预设情况下，Amazon Redshift 使用伪列 *\$1path* 和 *\$1size* 创建外部表。选择这些列可针对查询返回的每行查看 Amazon S3 上数据文件的路径以及数据文件的大小。*\$1path* 和 *\$1size* 列名称必须用双引号分隔。*SELECT \$1* 子句不返回 pseudocolumns。如下例所示，必须在查询中显式包含 *\$1path* 和 *\$1size* 列名称。

```
select "$path", "$size"
from spectrum.sales_part
where saledate = '2008-12-01';
```

您可以通过将 *spectrum\$1enable\$1pseudo\$1columns* 配置参数设置为 *false* 来禁用为会话创建 pseudocolumns 的功能。

**重要**  
选择 *\$1size* 或 *\$1path* 将产生费用，因为 Redshift Spectrum 会扫描 Amazon S3 中的数据文件来确定结果集的大小。有关更多信息，请参阅 [Amazon Redshift 定价](https://aws.amazon.com/redshift/pricing/)。

## 设置数据处理选项
<a name="r_CREATE_EXTERNAL_TABLE_usage-data-handling"></a>

您可以设置表参数以指定外部表中查询的数据的输入处理，其中包括：
+ 包含 VARCHAR、CHAR 和字符串数据的列中的多余字符。有关更多信息，请参阅外部表属性 `surplus_char_handling`。
+ 包含 VARCHAR、CHAR 和字符串数据的列中的无效字符。有关更多信息，请参阅外部表属性 `invalid_char_handling`。
+ 为外部表属性 `invalid_char_handling` 指定 REPLACE 时要使用的替换字符。
+ 包含整数和十进制数据的列的转换溢出处理。有关更多信息，请参阅外部表属性 `numeric_overflow_handling`。
+ Surplus\$1bytes\$1handling 为包含 varbyte 数据的列中的超额字节指定输入处理。有关更多信息，请参阅外部表属性 `surplus_bytes_handling`。

# 示例
<a name="r_CREATE_EXTERNAL_TABLE_examples"></a>

以下示例在名为 `spectrum` 的 Amazon Redshift 外部 schema 中创建一个名为 SALES 的表。数据位于制表符分隔的文本文件中。TABLE PROPERTIES 子句将 numRows 属性设置为 170000 行。

根据您用于运行 CREATE EXTERNAL TABLE 的身份，可能需要配置 IAM 权限。作为最佳实践，我们建议将权限策略附加到 IAM 角色，然后根据需要将其分配给用户和组。有关更多信息，请参阅 [Amazon Redshift 中的 Identity and Access Management](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-authentication-access-control.html)。

```
create external table spectrum.sales(
salesid integer,
listid integer,
sellerid integer,
buyerid integer,
eventid integer,
saledate date,
qtysold smallint,
pricepaid decimal(8,2),
commission decimal(8,2),
saletime timestamp)
row format delimited
fields terminated by '\t'
stored as textfile
location 's3://redshift-downloads/tickit/spectrum/sales/'
table properties ('numRows'='170000');
```

以下示例创建一个使用 JsonSerDe 以 JSON 格式引用数据的表。

```
create external table spectrum.cloudtrail_json (
event_version int,
event_id bigint,
event_time timestamp,
event_type varchar(10),
awsregion varchar(20),
event_name varchar(max),
event_source varchar(max),
requesttime timestamp,
useragent varchar(max),
recipientaccountid bigint)
row format serde 'org.openx.data.jsonserde.JsonSerDe'
with serdeproperties (
'dots.in.keys' = 'true',
'mapping.requesttime' = 'requesttimestamp'
) location 's3://amzn-s3-demo-bucket/json/cloudtrail';
```

以下 CREATE EXTERNAL TABLE AS 示例创建一个未分区的外部表。然后，它将 SELECT 查询的结果以 Apache Parquet 格式写入到目标 Amazon S3 位置。

```
CREATE EXTERNAL TABLE spectrum.lineitem
STORED AS parquet
LOCATION 'S3://amzn-s3-demo-bucket/cetas/lineitem/'
AS SELECT * FROM local_lineitem;
```

以下示例创建分区的外部表，并在 SELECT 查询中包含分区列。

```
CREATE EXTERNAL TABLE spectrum.partitioned_lineitem
PARTITIONED BY (l_shipdate, l_shipmode)
STORED AS parquet
LOCATION 'S3://amzn-s3-demo-bucket/cetas/partitioned_lineitem/'
AS SELECT l_orderkey, l_shipmode, l_shipdate, l_partkey FROM local_table;
```

如需外部数据目录中的现有数据库的列表，请查询 [SVV\$1EXTERNAL\$1DATABASES](r_SVV_EXTERNAL_DATABASES.md) 系统视图。

```
select eskind,databasename,esoptions from svv_external_databases order by databasename;
```

```
eskind | databasename | esoptions
-------+--------------+----------------------------------------------------------------------------------
     1 | default      | {"REGION":"us-west-2","IAM_ROLE":"arn:aws:iam::123456789012:role/mySpectrumRole"}
     1 | sampledb     | {"REGION":"us-west-2","IAM_ROLE":"arn:aws:iam::123456789012:role/mySpectrumRole"}
     1 | spectrumdb   | {"REGION":"us-west-2","IAM_ROLE":"arn:aws:iam::123456789012:role/mySpectrumRole"}
```

要查看外部表的详细信息，请查询 [SVV\$1EXTERNAL\$1TABLES](r_SVV_EXTERNAL_TABLES.md) 和 [SVV\$1EXTERNAL\$1COLUMNS](r_SVV_EXTERNAL_COLUMNS.md) 系统视图。

以下示例将查询 SVV\$1EXTERNAL\$1TABLES 视图。

```
select schemaname, tablename, location from svv_external_tables;
```

```
schemaname | tablename            | location
-----------+----------------------+--------------------------------------------------------
spectrum   | sales                | s3://redshift-downloads/tickit/spectrum/sales
spectrum   | sales_part           | s3://redshift-downloads/tickit/spectrum/sales_partition
```

以下示例将查询 SVV\$1EXTERNAL\$1COLUMNS 视图。

```
select * from svv_external_columns where schemaname like 'spectrum%' and tablename ='sales';
```

```
schemaname | tablename | columnname | external_type | columnnum | part_key
-----------+-----------+------------+---------------+-----------+---------
spectrum   | sales     | salesid    | int           |         1 |        0
spectrum   | sales     | listid     | int           |         2 |        0
spectrum   | sales     | sellerid   | int           |         3 |        0
spectrum   | sales     | buyerid    | int           |         4 |        0
spectrum   | sales     | eventid    | int           |         5 |        0
spectrum   | sales     | saledate   | date          |         6 |        0
spectrum   | sales     | qtysold    | smallint      |         7 |        0
spectrum   | sales     | pricepaid  | decimal(8,2)  |         8 |        0
spectrum   | sales     | commission | decimal(8,2)  |         9 |        0
spectrum   | sales     | saletime   | timestamp     |        10 |        0
```

要查看表分区，请使用以下查询。

```
select schemaname, tablename, values, location
from svv_external_partitions
where tablename = 'sales_part';
```

```
schemaname | tablename  | values         | location
-----------+------------+----------------+-------------------------------------------------------------------------
spectrum   | sales_part | ["2008-01-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-01
spectrum   | sales_part | ["2008-02-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-02
spectrum   | sales_part | ["2008-03-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-03
spectrum   | sales_part | ["2008-04-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-04
spectrum   | sales_part | ["2008-05-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-05
spectrum   | sales_part | ["2008-06-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-06
spectrum   | sales_part | ["2008-07-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-07
spectrum   | sales_part | ["2008-08-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-08
spectrum   | sales_part | ["2008-09-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-09
spectrum   | sales_part | ["2008-10-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-10
spectrum   | sales_part | ["2008-11-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-11
spectrum   | sales_part | ["2008-12-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-12
```

以下示例将为外部表返回相关数据文件的总大小。

```
select distinct "$path", "$size"
   from spectrum.sales_part;

 $path                                                                    | $size
--------------------------------------------------------------------------+-------
s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-01/ |  1616
s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-02/ |  1444
s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-02/ |  1444
```

## 分区示例
<a name="r_CREATE_EXTERNAL_TABLE_examples-partitioning"></a>

要创建按日期分区的外部表，请运行以下命令。

```
create external table spectrum.sales_part(
salesid integer,
listid integer,
sellerid integer,
buyerid integer,
eventid integer,
dateid smallint,
qtysold smallint,
pricepaid decimal(8,2),
commission decimal(8,2),
saletime timestamp)
partitioned by (saledate date)
row format delimited
fields terminated by '|'
stored as textfile
location 's3://redshift-downloads/tickit/spectrum/sales_partition/'
table properties ('numRows'='170000');
```

要添加分区，请运行以下 ALTER TABLE 命令。

```
alter table spectrum.sales_part
add if not exists partition (saledate='2008-01-01')
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-01/';
alter table spectrum.sales_part
add if not exists partition (saledate='2008-02-01')
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-02/';
alter table spectrum.sales_part
add if not exists partition (saledate='2008-03-01')
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-03/';
alter table spectrum.sales_part
add if not exists partition (saledate='2008-04-01')
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-04/';
alter table spectrum.sales_part
add if not exists partition (saledate='2008-05-01')
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-05/';
alter table spectrum.sales_part
add if not exists partition (saledate='2008-06-01')
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-06/';
alter table spectrum.sales_part
add if not exists partition (saledate='2008-07-01')
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-07/';
alter table spectrum.sales_part
add if not exists partition (saledate='2008-08-01')
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-08/';
alter table spectrum.sales_part
add if not exists partition (saledate='2008-09-01')
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-09/';
alter table spectrum.sales_part
add if not exists partition (saledate='2008-10-01')
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-10/';
alter table spectrum.sales_part
add if not exists partition (saledate='2008-11-01')
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-11/';
alter table spectrum.sales_part
add if not exists partition (saledate='2008-12-01')
location 's3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-12/';
```

要从分区表中选择数据，请运行以下查询。

```
select top 10 spectrum.sales_part.eventid, sum(spectrum.sales_part.pricepaid)
from spectrum.sales_part, event
where spectrum.sales_part.eventid = event.eventid
  and spectrum.sales_part.pricepaid > 30
  and saledate = '2008-12-01'
group by spectrum.sales_part.eventid
order by 2 desc;
```

```
eventid | sum
--------+---------
    914 | 36173.00
   5478 | 27303.00
   5061 | 26383.00
   4406 | 26252.00
   5324 | 24015.00
   1829 | 23911.00
   3601 | 23616.00
   3665 | 23214.00
   6069 | 22869.00
   5638 | 22551.00
```

要查看外部表分区，请查询 [SVV\$1EXTERNAL\$1PARTITIONS](r_SVV_EXTERNAL_PARTITIONS.md) 系统视图。

```
select schemaname, tablename, values, location from svv_external_partitions
where tablename = 'sales_part';
```

```
schemaname | tablename  | values         | location
-----------+------------+----------------+--------------------------------------------------
spectrum   | sales_part | ["2008-01-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-01
spectrum   | sales_part | ["2008-02-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-02
spectrum   | sales_part | ["2008-03-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-03
spectrum   | sales_part | ["2008-04-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-04
spectrum   | sales_part | ["2008-05-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-05
spectrum   | sales_part | ["2008-06-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-06
spectrum   | sales_part | ["2008-07-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-07
spectrum   | sales_part | ["2008-08-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-08
spectrum   | sales_part | ["2008-09-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-09
spectrum   | sales_part | ["2008-10-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-10
spectrum   | sales_part | ["2008-11-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-11
spectrum   | sales_part | ["2008-12-01"] | s3://redshift-downloads/tickit/spectrum/sales_partition/saledate=2008-12
```

## 行格式示例
<a name="r_CREATE_EXTERNAL_TABLE_examples-row-format"></a>

下面显示为以 AVRO 格式存储的数据文件指定 ROW FORMAT SERDE 参数的示例。

```
create external table spectrum.sales(salesid int, listid int, sellerid int, buyerid int, eventid int, dateid int, qtysold int, pricepaid decimal(8,2), comment VARCHAR(255))
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.avro.AvroSerDe'
WITH SERDEPROPERTIES ('avro.schema.literal'='{\"namespace\": \"dory.sample\",\"name\": \"dory_avro\",\"type\": \"record\", \"fields\": [{\"name\":\"salesid\", \"type\":\"int\"},
{\"name\":\"listid\", \"type\":\"int\"},
{\"name\":\"sellerid\", \"type\":\"int\"},
{\"name\":\"buyerid\", \"type\":\"int\"},
{\"name\":\"eventid\",\"type\":\"int\"},
{\"name\":\"dateid\",\"type\":\"int\"},
{\"name\":\"qtysold\",\"type\":\"int\"},
{\"name\":\"pricepaid\", \"type\": {\"type\": \"bytes\", \"logicalType\": \"decimal\", \"precision\": 8, \"scale\": 2}}, {\"name\":\"comment\",\"type\":\"string\"}]}')
STORED AS AVRO
location 's3://amzn-s3-demo-bucket/avro/sales' ;
```

下面显示了使用 RegEx 指定 ROW FORMAT SERDE 参数的示例。

```
create external table spectrum.types(
cbigint bigint,
cbigint_null bigint,
cint int,
cint_null int)
row format serde 'org.apache.hadoop.hive.serde2.RegexSerDe'
with serdeproperties ('input.regex'='([^\\x01]+)\\x01([^\\x01]+)\\x01([^\\x01]+)\\x01([^\\x01]+)')
stored as textfile
location 's3://amzn-s3-demo-bucket/regex/types';
```

下面显示了使用 Grok 指定 ROW FORMAT SERDE 参数的示例。

```
create external table spectrum.grok_log(
timestamp varchar(255),
pid varchar(255),
loglevel varchar(255),
progname varchar(255),
message varchar(255))
row format serde 'com.amazonaws.glue.serde.GrokSerDe'
with serdeproperties ('input.format'='[DFEWI], \\[%{TIMESTAMP_ISO8601:timestamp} #%{POSINT:pid:int}\\] *(?<loglevel>:DEBUG|FATAL|ERROR|WARN|INFO) -- +%{DATA:progname}: %{GREEDYDATA:message}')
stored as textfile
location 's3://DOC-EXAMPLE-BUCKET/grok/logs';
```

下面显示了一个有关在 S3 桶中定义 Amazon S3 服务器访问日志的示例。您可以使用 Redshift Spectrum 查询 Amazon S3 访问日志。

```
CREATE EXTERNAL TABLE spectrum.mybucket_s3_logs(
bucketowner varchar(255),
bucket varchar(255),
requestdatetime varchar(2000),
remoteip varchar(255),
requester varchar(255),
requested varchar(255),
operation varchar(255),
key varchar(255),
requesturi_operation varchar(255),
requesturi_key varchar(255),
requesturi_httpprotoversion varchar(255),
httpstatus varchar(255),
errorcode varchar(255),
bytessent bigint,
objectsize bigint,
totaltime varchar(255),
turnaroundtime varchar(255),
referrer varchar(255),
useragent varchar(255),
versionid varchar(255)
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
'input.regex' = '([^ ]*) ([^ ]*) \\[(.*?)\\] ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) \"([^ ]*)\\s*([^ ]*)\\s*([^ ]*)\" (- |[^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\") ([^ ]*).*$')
LOCATION 's3://amzn-s3-demo-bucket/s3logs’;
```

以下示例为 ION 格式的数据指定了 ROW FORMAT SERDE 参数。

```
CREATE EXTERNAL TABLE tbl_name (columns)
ROW FORMAT SERDE 'com.amazon.ionhiveserde.IonHiveSerDe'
STORED AS
INPUTFORMAT 'com.amazon.ionhiveserde.formats.IonInputFormat'
OUTPUTFORMAT 'com.amazon.ionhiveserde.formats.IonOutputFormat'
LOCATION 's3://amzn-s3-demo-bucket/prefix'
```

## 数据处理示例
<a name="r_CREATE_EXTERNAL_TABLE_examples-data-handling"></a>

以下示例访问该文件：[spi\$1global\$1rankings.csv](https://s3.amazonaws.com/redshift-downloads/docs-downloads/spi_global_rankings.csv)。您可以将 `spi_global_rankings.csv` 文件上载到 Amazon S3 桶以尝试这些示例。

以下示例创建外部架构 `schema_spectrum_uddh` 和数据库 `spectrum_db_uddh`。对于 `aws-account-id`，请输入您的 AWS 账户 ID，而对于 `role-name`，请输入您的 Redshift Spectrum 角色名称。

```
create external schema schema_spectrum_uddh
from data catalog
database 'spectrum_db_uddh'
iam_role 'arn:aws:iam::aws-account-id:role/role-name'
create external database if not exists;
```

以下示例在外部架构 `schema_spectrum_uddh` 中创建外部表 `soccer_league`。

```
CREATE EXTERNAL TABLE schema_spectrum_uddh.soccer_league
(
  league_rank smallint,
  prev_rank   smallint,
  club_name   varchar(15),
  league_name varchar(20),
  league_off  decimal(6,2),
  league_def  decimal(6,2),
  league_spi  decimal(6,2),
  league_nspi integer
)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n\l'
stored as textfile
LOCATION 's3://spectrum-uddh/league/'
table properties ('skip.header.line.count'='1');
```

请检查 `soccer_league` 表中的行数。

```
select count(*) from schema_spectrum_uddh.soccer_league;
```

此时将显示行数。

```
count
645
```

以下查询显示前 10 个俱乐部。由于俱乐部 `Barcelona` 字符串中包含无效字符，因此对该名称显示 NULL。

```
select league_rank,club_name,league_name,league_nspi
from schema_spectrum_uddh.soccer_league
where league_rank between 1 and 10;
```

```
league_rank	club_name	league_name			league_nspi
1		Manchester City	Barclays Premier Lea		34595
2		Bayern Munich	German Bundesliga		34151
3		Liverpool	Barclays Premier Lea		33223
4		Chelsea		Barclays Premier Lea		32808
5		Ajax		Dutch Eredivisie		32790
6		Atletico 	Madrid	Spanish Primera Divi	31517
7		Real Madrid	Spanish Primera Divi		31469
8		NULL	        Spanish Primera Divi            31321
9		RB Leipzig	German Bundesliga		31014
10		Paris Saint-Ger	French Ligue 1			30929
```

以下示例更改了 `soccer_league` 表，以指定用于插入一个问号 (?) 来替换意外字符的 `invalid_char_handling`、`replacement_char` 和 `data_cleansing_enabled` 外部表属性。

```
alter  table schema_spectrum_uddh.soccer_league
set table properties ('invalid_char_handling'='REPLACE','replacement_char'='?','data_cleansing_enabled'='true');
```

以下示例将查询排名从 1 到 10 的团队的表 `soccer_league`。

```
select league_rank,club_name,league_name,league_nspi
from schema_spectrum_uddh.soccer_league
where league_rank between 1 and 10;
```

由于表属性已更改，结果显示了前 10 位俱乐部，在第八行中对于俱乐部 `Barcelona` 采用问号 (?) 替换字符。

```
league_rank	club_name	league_name		league_nspi
1		Manchester City	Barclays Premier Lea	34595
2		Bayern Munich	German Bundesliga	34151
3		Liverpool	Barclays Premier Lea	33223
4		Chelsea		Barclays Premier Lea	32808
5		Ajax		Dutch Eredivisie	32790
6		Atletico Madrid	Spanish Primera Divi	31517
7		Real Madrid	Spanish Primera Divi	31469
8		Barcel?na	Spanish Primera Divi	31321
9		RB Leipzig	German Bundesliga	31014
10		Paris Saint-Ger	French Ligue 1		30929
```

以下示例更改了 `soccer_league` 表，以指定用于剔除包含意外字符的行的 `invalid_char_handling` 外部表属性。

```
alter table schema_spectrum_uddh.soccer_league
set table properties ('invalid_char_handling'='DROP_ROW','data_cleansing_enabled'='true');
```

以下示例将查询排名从 1 到 10 的团队的表 `soccer_league`。

```
select league_rank,club_name,league_name,league_nspi
from schema_spectrum_uddh.soccer_league
where league_rank between 1 and 10;
```

结果显示排名靠前的俱乐部，不包括对应于俱乐部 `Barcelona` 的第八行。

```
league_rank   club_name         league_name            league_nspi
1             Manchester City   Barclays Premier Lea   34595
2             Bayern Munich     German Bundesliga      34151
3             Liverpool         Barclays Premier Lea   33223
4             Chelsea           Barclays Premier Lea   32808
5             Ajax              Dutch Eredivisie       32790
6             Atletico Madrid   Spanish Primera Divi   31517
7             Real Madrid       Spanish Primera Divi   31469
9             RB Leipzig        German Bundesliga      31014
10            Paris Saint-Ger   French Ligue 1         30929
```

# CREATE EXTERNAL VIEW
<a name="r_CREATE_EXTERNAL_VIEW"></a>

Data Catalog 视图预览功能仅在以下区域中可用。
+ 美国东部（俄亥俄州）(us-east-2)
+ 美国东部（弗吉尼亚州北部）(us-east-1)
+ 美国西部（北加利福尼亚）(us-west-1)
+ 亚太地区（东京）(ap-northeast-1)
+ 欧洲地区（爱尔兰）(eu-west-1)
+ 欧洲地区（斯德哥尔摩）(eu-north-1)

在 Data Catalog 中创建视图。Data Catalog 视图是一种单一视图架构，可与其他 SQL 引擎（如 Amazon Athena 和 Amazon EMR）配合使用。您可以通过选择的引擎查询视图。有关 Data Catalog 视图的更多信息，请参阅[创建 Data Catalog 视图](https://docs.aws.amazon.com/redshift/latest/dg/data-catalog-views-overview.html)。

## 语法
<a name="r_CREATE_EXTERNAL_VIEW-synopsis"></a>

```
CREATE EXTERNAL VIEW schema_name.view_name [ IF NOT EXISTS ]
{catalog_name.schema_name.view_name | awsdatacatalog.dbname.view_name | external_schema_name.view_name}
AS query_definition;
```

## 参数
<a name="r_CREATE_EXTERNAL_VIEW-parameters"></a>

 *schema\$1name.view\$1name*   
附加到 AWS Glue 数据库的架构，后面是视图的名称。

PROTECTED  
指定只有在 query\$1definition 中的查询能成功完成时，CREATE EXTERNAL VIEW 命令才能完成。

IF NOT EXISTS  
如果视图尚不存在，则创建该视图。

catalog\$1name.schema\$1name.view\$1name \$1 awsdatacatalog.dbname.view\$1name \$1 external\$1schema\$1name.view\$1name  
创建视图时要使用的架构符号。可以指定使用您创建的 Glue 数据库 AWS Glue Data Catalog 或您创建的外部架构。有关更多信息，请参阅 [CREATE DATABASE](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_DATABASE.html) 和 [CREATE EXTERNAL SCHEMA](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_SCHEMA.html)。

 *query\$1definition*   
Amazon Redshift 为更改视图而运行的 SQL 查询的定义。

## 示例
<a name="r_CREATE_EXTERNAL_VIEW-examples"></a>

以下示例创建一个名为 sample\$1schema.glue\$1data\$1catalog\$1view 的 Data Catalog 视图。

```
CREATE EXTERNAL PROTECTED VIEW sample_schema.glue_data_catalog_view IF NOT EXISTS
AS SELECT * FROM sample_database.remote_table "remote-table-name";
```

# CREATE FUNCTION
<a name="r_CREATE_FUNCTION"></a>

使用 SQL SELECT 子句或 Python 程序创建新的标量用户定义的函数 (UDF)。

有关更多信息以及示例，请参阅 [Amazon Redshift 中用户定义的函数](user-defined-functions.md)。

## 所需的权限
<a name="r_CREATE_FUNCTION-privileges"></a>

您必须通过以下方式之一获得权限，才能运行 CREATE OR REPLACE FUNCTION：
+ CREATE FUNCTION：
  + 超级用户可以使用可信和不受信任的语言来创建函数。
  + 具有 CREATE [ OR REPLACE ] FUNCTION 权限的用户可以使用可信语言创建函数。
+ REPLACE FUNCTION：
  + Superuser
  + 具有 CREATE [ OR REPLACE ] FUNCTION 权限的用户
  + 函数拥有者

## 语法
<a name="r_CREATE_FUNCTION-synopsis"></a>

```
CREATE [ OR REPLACE ] FUNCTION f_function_name
( { [py_arg_name  py_arg_data_type |
sql_arg_data_type } [ , ... ] ] )
RETURNS data_type
{ VOLATILE | STABLE | IMMUTABLE }
AS $$
  { python_program | SELECT_clause }
$$ LANGUAGE { plpythonu | sql }
```

## 参数
<a name="r_CREATE_FUNCTION-parameters"></a>

OR REPLACE  
指定如果某个函数与已存在的此函数具有相同的名称和输入参数数据类型或*签名*，则替换现有的函数。您只能将某个函数替换为定义一组相同数据类型的新函数。您必须是超级用户才能替换函数。  
如果您定义的函数与现有函数具有相同的名称，但签名不同，则创建新的函数。换而言之，函数名称将会重载。有关更多信息，请参阅 [重载函数名称](udf-naming-udfs.md#udf-naming-overloading-function-names)。

 *f\$1function\$1name*   
函数的名称。如果您指定 schema 名称（例如 `myschema.myfunction`），则使用指定的 schema 创建函数。否则，将在当前 schema 中创建该函数。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。  
我们建议您将所有 UDF 名称添加前缀 `f_`。Amazon Redshift 保留 `f_` 前缀供 UDF 名称使用。因此，使用 `f_` 前缀，您可以确保您的 UDF 名称不会与现有或未来的 Amazon Redshift 内置 SQL 函数名称冲突。有关更多信息，请参阅 [防止 UDF 命名冲突](udf-naming-udfs.md)。  
如果输入参数的数据类型不同，您可以定义多个具有相同函数名称的函数。换而言之，函数名称将会重载。有关更多信息，请参阅 [重载函数名称](udf-naming-udfs.md#udf-naming-overloading-function-names)。

 *py\$1arg\$1name py\$1arg\$1data\$1type \$1 sql\$1arg\$1data\$1type*   
对于 Python UDF，为参数名称和数据类型的列表。对于 SQL UDF，为数据类型的列表，不含参数名称。在 Python UDF 中，使用参数名称引用参数。在 SQL UDF 中，使用 \$11、\$12 等基于参数在参数列表中的顺序引用参数。  
对于 SQL UDF，输入和返回数据类型可以是任何标准 Amazon Redshift 数据类型。对于 Python UDF，输入和返回数据类型可以为 SMALLINT、INTEGER、BIGINT、DECIMAL、REAL、DOUBLE PRECISION、BOOLEAN、CHAR、VARCHAR、DATE 或 TIMESTAMP。此外，Python 用户定义的函数 (UDF) 支持数据类型 ANYELEMENT。此数据类型会根据在运行时提供的相应参数的数据类型，自动转换为标准数据类型。如果多个参数使用 ANYELEMENT，则它们会根据列表中的第一个 ANYELEMENT 参数，在运行时全部解析为相同的数据类型。有关更多信息，请参阅[Python UDF 数据类型](udf-data-types.md)和[数据类型](c_Supported_data_types.md)。  
您可以指定最多 32 个参数。

 RETURNS *data\$1type*   
函数返回的值的数据类型。RETURNS 数据类型可以是任何标准的 Amazon Redshift 数据类型。此外，Python UDF 可以使用 ANYELEMENT 数据类型，它会根据在运行时提供的参数，自动转换为标准数据类型。如果您为返回数据类型指定 ANYELEMENT，则至少有一个参数必须使用 ANYELEMENT。在调用函数时，实际返回数据类型会匹配为 ANYELEMENT 参数提供的数据类型。有关更多信息，请参阅 [Python UDF 数据类型](udf-data-types.md)。

 VOLATILE \$1 STABLE \$1 IMMUTABLE   
通知查询优化程序有关函数的不稳定性。  
如果您将函数标记为其有效的最严格稳定性类别，您将获得最大程度的优化。但是，如果类别过于严格，则存在优化程序错误地忽略某些调用的风险，从而导致不正确的结果集。按照严格性顺序，从最不严格的开始，稳定性类别如下所示：  
+ VOLATILE
+ STABLE
+ IMMUTABLE
VOLATILE  
对于相同的参数，函数会对连续的调用返回不同的结果，甚至对于单个语句中的行也是如此。优化查询程序无法对不稳定函数的行为做出任何假设，因此使用不稳定函数的查询必须对每个输入行重新计算该函数。  
STABLE  
对于相同的参数，可保证函数对在单个语句内处理的所有行返回相同的结果。在不同的语句中调用时，函数可能会返回不同的结果。此类别使优化程序能够将单个语句内对该函数的多个调用优化为对该语句的单个调用。  
IMMUTABLE  
对于相同的参数，函数始终返回相同的结果。当查询使用常量参数调用 `IMMUTABLE` 函数时，优化程序会预先计算函数。

AS \$1\$1 *statement* \$1\$1  
 包含要执行的语句的构造。需要文字关键字 `AS $$` 和 `$$`。  
Amazon Redshift 要求您使用称为“美元引号”的格式，在您的函数中包含语句。包含的任何内容将按原样传递。您不必对任何特殊字符进行转义，因为字符串的内容是按照其字面涵义编写的。  
 通过*美元引号* 格式，您可以使用一对美元符号 (\$1\$1) 来指示要运行的语句的开头和结尾，如以下示例所示。  

```
$$ my statement $$
```
 （可选）在每对美元符号之间，可以指定字符串来帮助识别语句。您使用的字符串必须在括起字符对的开始和结束都是相同的。该字符串区分大小写，它遵循与不带括起字符的标识符相同的约束，但有一点除外，它不能包含美元符号。以下示例使用字符串 `test`。  

```
$test$ my statement $test$
```
有关“美元引号”格式的更多信息，请参阅 PostgreSQL 文档的[词法结构](https://www.postgresql.org/docs/9.4/static/sql-syntax-lexical.html)中的“使用美元符号括起的常量字符串”。

*python\$1program*   
返回值的有效 Python 可执行程序。您在函数中传递的语句必须符合 Python 网站上的 [Python 代码样式指南](https://www.python.org/dev/peps/pep-0008/#indentation)中规定的缩进要求。有关更多信息，请参阅 [适用于 UDF 的 Python 语言支持](udf-python-language-support.md)。

*SQL\$1clause*   
SQL SELECT 子句。  
SELECT 子句不能包含以下任何类型的子句：  
+ FROM
+ INTO
+ WHERE
+ GROUP BY
+ ORDER BY
+ LIMIT

LANGUAGE \$1 plpythonu \$1 sql \$1   
对于 Python，指定 `plpythonu`。对于 SQL，指定 `sql`。您必须具有使用 SQL 或 plpythonu 语言的权限。有关更多信息，请参阅 [UDF 安全性和权限](udf-security-and-privileges.md)。

## 使用说明
<a name="r_CREATE_FUNCTION-usage-notes"></a>

### 嵌套函数
<a name="r_CREATE_FUNCTION-usage-notes-nested-functions"></a>

您可以从一个 SQL UDF 中调用另一个 SQL 用户定义函数 (UDF)。当您运行 CREATE FUNCTION 命令时，嵌套函数必须存在。Amazon Redshift 不会跟踪 UDF 的依赖项，因此，如果您删除嵌套函数，Amazon Redshift 不会返回错误。但是，如果嵌套函数不存在，则 UDF 将失败。例如，以下函数调用 SELECT 子句中的 `f_sql_greater `函数。

```
create function f_sql_commission (float, float )
  returns float
stable
as $$
  select f_sql_greater ($1, $2)
$$ language sql;
```

### UDF 安全性和权限
<a name="r_CREATE_FUNCTION-usage-notes-security-and-privileges"></a>

要创建 UDF，您必须具有使用 SQL 或 plpythonu (Python) 语言的权限。默认情况下，向 PUBLIC 授予 USAGE ON LANGUAGE SQL。但是，您必须明确授予 USAGE ON LANGUAGE PLPYTHONU 权限才能指定用户或组。

要撤销 SQL 的使用权限，请先从 PUBLIC 撤销使用权限。然后，仅向允许创建 SQL UDF 的特定用户或组授予 SQL 使用权限。以下示例将从 PUBLIC 撤销对 SQL 的使用权限，然后向用户组 `udf_devs` 授予使用权限。

```
revoke usage on language sql from PUBLIC;
grant usage on language sql to group udf_devs;
```

要运行 UDF，您必须拥有每个函数的执行权限。默认情况下，向 PUBLIC 授予新 UDF 的执行权限。要限制使用，请从 PUBLIC 撤消函数的执行权限。然后向特定的个人或组授予权限。

以下示例从 PUBLIC 撤消了对函数 `f_py_greater` 的执行权限，然后向用户组 `udf_devs` 授予使用权限。

```
revoke execute on function f_py_greater(a float, b float) from PUBLIC;
grant execute on function f_py_greater(a float, b float) to group udf_devs;
```

默认情况下，超级用户拥有全部权限。

有关更多信息，请参阅[GRANT](r_GRANT.md)和[REVOKE](r_REVOKE.md)。

## 示例
<a name="r_CREATE_FUNCTION-examples"></a>

### 标量 Python UDF 示例
<a name="r_CREATE_FUNCTION-python-example"></a>

以下示例创建用于比较两个整数值并返回较大值的 Python UDF。

```
create function f_py_greater (a float, b float)
  returns float
stable
as $$
  if a > b:
    return a
  return b
$$ language plpythonu;
```

以下示例查询 SALES 表并调用新的 `f_py_greater` 函数，以返回 COMMISSION 和 PRICEPAID 的 20% 这两个值中较大的值。

```
select f_py_greater (commission, pricepaid*0.20) from sales;
```

### 标量 SQL UDF 示例
<a name="r_CREATE_FUNCTION-sql-example"></a>

以下示例创建一个用于比较两个数并返回较大值的函数。

```
create function f_sql_greater (float, float)
  returns float
stable
as $$
  select case when $1 > $2 then $1
    else $2
  end
$$ language sql;
```

以下查询将调用新的 `f_sql_greater` 函数以查询 SALES 表，并返回 COMMISSION 或 PRICEPAID 的 20% (两个值中的较大者)。

```
select f_sql_greater (commission, pricepaid*0.20) from sales;
```

# CREATE GROUP
<a name="r_CREATE_GROUP"></a>

定义新的用户组。只有超级用户可以创建组。

## 语法
<a name="r_CREATE_GROUP-synopsis"></a>

```
CREATE GROUP group_name
[ [ WITH ] [ USER username ] [, ...] ]
```

## 参数
<a name="r_CREATE_GROUP-parameters"></a>

 *group\$1name*   
新用户组的名称。以两个下划线开头的组名保留供 Amazon Redshift 内部使用。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。

WITH  
可选语法，用于指示 CREATE GROUP 的额外参数。

USER  
向组中添加一个或多个用户。

 *username*   
要添加到组中的用户的名称。

## 示例
<a name="r_CREATE_GROUP-examples"></a>

以下示例创建名为 ADMIN\$1GROUP 的用户组，其中包含两个用户 ADMIN1 和 ADMIN2。

```
create group admin_group with user admin1, admin2;
```

# CREATE IDENTITY PROVIDER
<a name="r_CREATE_IDENTITY_PROVIDER"></a>

定义新的身份提供者。只有超级用户可以创建身份提供者。

## 语法
<a name="r_CREATE_IDENTITY_PROVIDER-synopsis"></a>

```
CREATE IDENTITY PROVIDER identity_provider_name TYPE type_name
NAMESPACE namespace_name
[PARAMETERS parameter_string]
[APPLICATION_ARN arn]
[IAM_ROLE iam_role]
[AUTO_CREATE_ROLES
    [ TRUE [ { INCLUDE | EXCLUDE } GROUPS LIKE filter_pattern] |
      FALSE
    ]
  ];
```

## 参数
<a name="r_CREATE_IDENTITY_PROVIDER-parameters"></a>

 *identity\$1provider\$1name*   
新身份提供者的名称。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。

*type\$1name*  
要与之交互的身份提供者。Azure 和 AWSIDC 是目前受支持的仅有身份提供者。

*namespace\$1name*  
命名空间。这是身份提供者目录的唯一速记标识符。

 *parameter\$1string*   
一个包含格式正确的 JSON 对象的字符串，其中包含身份提供者所需的参数和值。

 *arn*   
IAM Identity Center 托管应用程序的 Amazon 资源名称（ARN）。仅当身份提供者类型为 AWSIDC 时，此参数才适用。

 *iam\$1role*   
提供连接到 IAM Identity Center 的权限的 IAM 角色。仅当身份提供者类型为 AWSIDC 时，此参数才适用。

 *auto\$1create\$1roles*   
启用或禁用自动创建角色特征。如果该值为 TRUE，则 Amazon Redshift 启用自动创建角色功能。如果该值为 FALSE，则 Amazon Redshift 禁用自动创建角色功能。如果未指定此参数的值，Amazon Redshift 将使用以下逻辑确定该值：  
+  如果提供了 `AUTO_CREATE_ROLES` 但未指定值，则该值设置为 TRUE。
+  如果未提供 `AUTO_CREATE_ROLES` 且身份提供者为 AWSIDC，则该值设置为 FALSE。
+  如果未提供 `AUTO_CREATE_ROLES` 且身份提供者为 Azure，则该值设置为 TRUE。
要包括组，请指定 `INCLUDE`。默认值为空，这意味着如果 `AUTO_CREATE_ROLES` 为开启，则包括所有组。  
要排除组，请指定 `EXCLUDE`。默认值为空，这意味着如果 `AUTO_CREATE_ROLES` 为开启，则不排除任何组。

 *filter\$1pattern*   
一个有效的 UTF-8 字符表达式，具有与组名称匹配的模式。LIKE 选项执行区分大小写的匹配，支持以下模式匹配元字符：      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_CREATE_IDENTITY_PROVIDER.html)
如果 *filter\$1pattern* 不包含元字符，则模式仅表示字符串本身；在此情况下，LIKE 的行为与等于运算符相同。  
*filter\$1pattern* 支持以下字符：  
+  大写和小写字母字符（A-Z 和 a-z） 
+  数字（0-9） 
+  以下特殊字符：

  ```
  _ % ^ * + ? { } , $
  ```

## 示例
<a name="r_CREATE_IDENTITY_PROVIDER-examples"></a>

下面的示例创建一个名为 *oauth\$1standard*、TYPE 为 *azure* 的身份提供者，以与 Microsoft Azure Active Directory (AD) 建立通信。

```
CREATE IDENTITY PROVIDER oauth_standard TYPE azure
NAMESPACE 'aad'
PARAMETERS '{"issuer":"https://sts.windows.net/2sdfdsf-d475-420d-b5ac-667adad7c702/",
"client_id":"87f4aa26-78b7-410e-bf29-57b39929ef9a",
"client_secret":"BUAH~ewrqewrqwerUUY^%tHe1oNZShoiU7",
"audience":["https://analysis.windows.net/powerbi/connector/AmazonRedshift"]
}'
```

您可以将 IAM Identity Center 托管应用程序与现有预调配集群或 Amazon Redshift Serverless 工作组进行连接。这使您能够通过 IAM Identity Center 管理对 Redshift 数据库的访问权限。为此，请运行如以下示例所示的 SQL 命令。您必须是数据库管理员。

```
CREATE IDENTITY PROVIDER "redshift-idc-app" TYPE AWSIDC
NAMESPACE 'awsidc'
APPLICATION_ARN 'arn:aws:sso::123456789012:application/ssoins-12345f67fe123d4/apl-a0b0a12dc123b1a4'
IAM_ROLE 'arn:aws:iam::123456789012:role/MyRedshiftRole';
```

在本例中，应用程序 ARN 标识要连接到的托管应用程序。您可以通过运行 `SELECT * FROM SVV_IDENTITY_PROVIDERS;` 找到该应用程序。

有关使用 CREATE IDENTITY PROVIDER 的更多信息，包括其他示例，请参阅 [Amazon Redshift 的原生身份提供者 (IdP) 联合身份验证](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-native-idp.html)。有关设置从 Redshift 到 IAM Identity Center 的连接的更多信息，请参阅[将 Redshift 与 IAM Identity Center 连接，为用户提供单点登录体验](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-idp-connect.html)。

# CREATE LIBRARY
<a name="r_CREATE_LIBRARY"></a>

安装一个 Python 库，在使用 [CREATE FUNCTION](r_CREATE_FUNCTION.md) 命令创建用户定义的函数 (UDF) 时，用户可使用该库进行整合。用户安装的库的总大小不能超过 100MB。

CREATE LIBRARY 无法在事务块 (BEGIN … END) 内运行。有关事务的更多信息，请参阅 [Amazon Redshift 中的隔离级别](c_serial_isolation.md)。

Amazon Redshift 支持 Python 2.7 版本。有关更多信息，请参阅 [www.python.org](https://www.python.org/)。

有关更多信息，请参阅 [示例：导入自定义 Python 库模块](udf-importing-custom-python-library-modules.md)。

## 所需的权限
<a name="r_CREATE_LIBRARY-privileges"></a>

以下是 CREATE LIBRARY 所需的权限：
+ Superuser
+ 具有 CREATE LIBRARY 权限或具有指定语言权限的用户

## 语法
<a name="r_CREATE_LIBRARY-synopsis"></a>

```
CREATE [ OR REPLACE ] LIBRARY library_name LANGUAGE plpythonu
FROM
{ 'https://file_url'
| 's3://bucketname/file_name'
authorization
  [ REGION [AS] 'aws_region']
  IAM_ROLE { default | ‘arn:aws:iam::<AWS 账户-id>:role/<role-name>’ }
}
```

## 参数
<a name="r_CREATE_LIBRARY-parameters"></a>

OR REPLACE  
指定如果存在与已存在的库同名的库，则替换现有库。REPLACE 将立即提交。如果依赖于所替换库的 UDF 正在并行运行，UDF 可能失败或返回意外结果，即使 UDF 正在事务中运行也是如此。您必须是所有者或超级用户才能替换库。

 *library\$1name*   
要安装的库的名称。无法创建包含与 Python Standard Library 模块或 Amazon Redshift 预安装的 Python 模块同名的模块的库。如果现有用户安装的库与要安装的库使用相同的 Python 包，则必须先删除现有库，然后再安装新库。有关更多信息，请参阅 [适用于 UDF 的 Python 语言支持](udf-python-language-support.md)。

LANGUAGE plpythonu  
要使用的语言。Python (plpythonu) 是唯一支持的语言。Amazon Redshift 支持 Python 2.7 版本。有关更多信息，请参阅 [www.python.org](https://www.python.org/)。

FROM  
库文件的位置。您可以指定 Amazon S3 桶和对象名称，也可以指定用于从公共网站下载文件的 URL。必须以 `.zip` 文件的形式打包库。有关更多信息，请参阅 Python 文档中的[构建和安装 Python 模块](https://docs.python.org/2/library/distutils.html?highlight=distutils#module-distutils)。

 https://*file\$1url*   
用于从公共网站下载文件的 URL。URL 最多可包含三个重定向。以下是文件 URL 的示例。  

```
'https://www.example.com/pylib.zip'
```

 s3://*bucket\$1name/file\$1name*   
包含库文件的单个 Amazon S3 对象的路径。以下是 Amazon S3 对象路径的示例。  

```
's3://amzn-s3-demo-bucket/my-pylib.zip'
```
如果您指定 Amazon S3 桶，则还必须为有权下载该文件的 AWS 用户提供凭证。  
 如果 Amazon S3 桶不在您的 Amazon Redshift 集群所在的 AWS 区域内，则必须使用 REGION 选项指定数据所在的 AWS 区域。*aws\$1region* 的值必须匹配 COPY 命令的 [REGION](copy-parameters-data-source-s3.md#copy-region) 参数描述中的表中所列的 AWS 区域。

*授权*   
一个子句，指示您的集群在访问包含库文件的 Amazon S3 桶时使用的身份验证和授权方法。您的集群必须有权利用 LIST 和 GET 操作访问 Amazon S3。  
authorization 的语法与 COPY 命令 authorization 的语法相同。有关更多信息，请参阅 [授权参数](copy-parameters-authorization.md)。  

```
IAM_ROLE { default | ‘arn:aws:iam::<AWS 账户-id>:role/<role-name>’
```
 使用默认关键字让 Amazon Redshift 使用设置为默认值并在 CREATE LIBRARY 命令运行时与集群关联的 IAM 角色。  
使用 IAM 角色的 Amazon 资源名称（ARN），您的集群使用该角色进行身份验证和授权。如果您指定 IAM\$1ROLE，则无法使用 ACCESS\$1KEY\$1ID 和 SECRET\$1ACCESS\$1KEY、SESSION\$1TOKEN 或 CREDENTIALS。  
（可选）如果 Amazon S3 桶使用服务器端加密，也可以在 credentials-args 字符串中提供加密密钥。如果您使用临时安全凭证，请在 *credentials-args* 字符串中提供临时令牌。  
有关更多信息，请参阅 [临时安全凭证](copy-usage_notes-access-permissions.md#r_copy-temporary-security-credentials)。

 REGION [AS] *aws\$1region*   
Amazon S3 桶所在的 AWS 区域。当 Amazon S3 桶与 Amazon Redshift 集群不在同一个 AWS 区域时，需要 REGION。*aws\$1region* 的值必须匹配 COPY 命令的 [REGION](copy-parameters-data-source-s3.md#copy-region) 参数描述中的表中所列的 AWS 区域。  
预设情况下，CREATE LIBRARY 假定 Amazon S3 桶位于 Amazon Redshift 集群所在的 AWS 区域。

## 示例
<a name="r_CREATE_LIBRARY-examples"></a>

以下两个示例将安装 [urlparse](https://docs.python.org/2/library/urlparse.html#module-urlparse) Python 模块，该模块会打包到名为 `urlparse3-1.0.3.zip` 的文件中。

以下命令从已上载到位于美国东部区域的 Amazon S3 桶的包安装名为 `f_urlparse` 的 UDF 库。

```
create library f_urlparse
language plpythonu
from 's3://amzn-s3-demo-bucket/urlparse3-1.0.3.zip'
credentials 'aws_iam_role=arn:aws:iam::<aws-account-id>:role/<role-name>'
region as 'us-east-1';
```

以下示例从网站上的库文件安装名为 `f_urlparse` 的库。



```
create library f_urlparse
language plpythonu
from 'https://example.com/packages/urlparse3-1.0.3.zip';
```

# CREATE MASKING POLICY
<a name="r_CREATE_MASKING_POLICY"></a>

创建新的动态数据掩蔽策略以模糊处理给定格式的数据。有关动态数据掩蔽的更多信息，请参阅 [动态数据掩蔽](t_ddm.md)。

超级用户和具有 sys:secadmin 角色的用户或角色可以创建屏蔽策略。

## 语法
<a name="r_CREATE_MASKING_POLICY-synopsis"></a>

```
CREATE MASKING POLICY 
   { policy_name | database_name.policy_name } [IF NOT EXISTS]
   WITH (input_columns)
   USING (masking_expression);
```

## 参数
<a name="r_CREATE_MASKING_POLICY-parameters"></a>

 *policy\$1name*   
屏蔽策略的名称。屏蔽策略不能与数据库中已存在的另一个屏蔽策略的名称相同。

database\$1name  
将在其中创建策略的数据库的名称。可以在连接的数据库或 Amazon Redshift 联合身份验证权限目录上创建策略。

*input\$1columns*   
格式为 (col1 type, col2 type ...) 的列名元组。  
列名用作屏蔽表达式的输入。列名不必与要掩蔽的列的名称相匹配，但输入和输出数据类型必须匹配。

*masking\$1expression*  
用于转换目标列的 SQL 表达式。可以使用诸如字符串操作函数之类的数据操作函数来编写该表达式，也可以与使用 SQL、Python 或 AWS Lambda 编写的用户定义函数结合使用。您可以让具有多个输出的屏蔽策略包括一个列表达式元组。如果您使用常量作为掩蔽表达式，则必须将其显式转换为与输入类型匹配的类型。  
 您必须对在屏蔽表达式中使用的任何用户定义函数具有 USAGE 权限。

有关在 Amazon Redshift 联合身份验证权限目录上使用 CREATE MASKING POLICY 的信息，请参阅[使用 Amazon Redshift 联合身份验证权限管理访问控制](https://docs.aws.amazon.com/redshift/latest/dg/federated-permissions-managing-access.html)。

# CREATE MATERIALIZED VIEW
<a name="materialized-view-create-sql-command"></a>

基于一个或多个 Amazon Redshift 表创建实体化视图。您还可以将实体化视图建立在使用 Spectrum 或联合查询创建的外部表的基础上。有关 Spectrum 的信息，请参阅[Amazon Redshift Spectrum](c-using-spectrum.md)。有关联合查询的信息，请参阅 [在 Amazon Redshift 中使用联合查询来查询数据](federated-overview.md)。

## 语法
<a name="mv_CREATE_MATERIALIZED_VIEW-synopsis"></a>

```
CREATE MATERIALIZED VIEW mv_name
[ BACKUP { YES | NO } ]
[ table_attributes ]
[ AUTO REFRESH { YES | NO } ]
AS query
```

## 参数
<a name="mv_CREATE_MATERIALIZED_VIEW-parameters"></a>

BACKUP  
一个子句，指定实体化视图是否应包含在自动和手动集群快照中。  
对于没有包含关键数据的实体化视图，请指定 BACKUP NO 以节省在创建快照以及从快照还原时的处理时间，并减小在 Amazon Simple Storage Service 上占用的存储空间。BACKUP NO 设置不会影响数据自动复制到集群内的其他节点，因此当发生节点故障时，指定了 BACKUP NO 的实体化视图将被还原。默认值为 BACKUP YES。

 *table\$1attributes*   
用于指定实体化视图中数据的分布方式的子句，包括以下内容：  
+  实体化视图的分配方式，格式为 `DISTSTYLE { EVEN | ALL | KEY }`。如果忽略此子句，则分配方式为 `EVEN`。有关更多信息，请参阅 [分配方式](c_choosing_dist_sort.md)。
+ 实体化视图的分配键，格式为 `DISTKEY ( distkey_identifier )`。有关更多信息，请参阅 [指定分配方式](t_designating_distribution_styles.md)。
+ 实体化视图的排序键，格式为 `SORTKEY ( column_name [, ...] )`。有关更多信息，请参阅 [排序键](t_Sorting_data.md)。

AS *query*  
一个定义实体化视图及其内容的有效 `SELECT` 语句。来自查询的结果集定义了实体化视图的列和行。有关创建实体化视图时的限制的信息，请参阅[限制](#mv_CREATE_MATERIALIZED_VIEW-limitations)。  
此外，查询中使用的具体 SQL 语言结构将决定实体化视图可进行增量刷新还是完全刷新。有关刷新方法的信息，请参阅 [REFRESH MATERIALIZED VIEW](materialized-view-refresh-sql-command.md)。有关增量刷新的限制的信息，请参阅[增量刷新限制](materialized-view-refresh-sql-command.md#mv_REFRESH_MARTERIALIZED_VIEW_limitations)。  
如果查询包含的 SQL 命令不支持递增刷新，则 Amazon Redshift 会显示一条消息，指示实体化视图将使用完全刷新。该消息可能显示，也可能不显示，具体取决于 SQL 客户端应用程序。选中 `state` 的 [STV\$1MV\$1INFO](r_STV_MV_INFO.md) 列可查看实体化视图使用的刷新类型。

AUTO REFRESH  
一个子句，用于定义是否应使用其基表中的最新更改自动刷新实体化视图。默认值为 `NO`。有关更多信息，请参阅 [刷新实体化视图](materialized-view-refresh.md)。

## 使用说明
<a name="mv_CREATE_MARTERIALIZED_VIEW_usage"></a>

要创建实体化视图，您必须具有以下权限：
+ 针对架构的 CREATE 权限。
+ 对基表具有表级或列级 SELECT 权限以创建实体化视图。如果您对特定列具有列级权限，则可以仅在这些列上创建实体化视图。

 通过在 `mv_name` 中提供外部数据库名称，可以从远程数据共享集群创建实体化视图。

## 对数据共享中的实体化视图进行增量刷新
<a name="mv_CREATE_MARTERIALIZED_VIEW_datashare"></a>

 在共享基表时，Amazon Redshift 支持对消费者数据共享中的实体化视图进行自动和增量刷新。增量刷新是一项操作，其中 Amazon Redshift 可识别上次刷新后发生的一个或多个基表中的更改，并仅更新实体化视图中的相应记录。与完全刷新相比，这项操作的运行速度更快，并且可以提高工作负载性能。您不必为了利用增量刷新而更改实体化视图的定义。

在实体化视图中使用增量刷新时，有几个限制需要注意：
+ 无论是本地数据库还是远程数据库，实体化视图只能引用一个数据库。
+ 增量刷新仅适用于新的实体化视图。因此，您必须删除现有的实体化视图并重新创建它们，才能进行增量刷新。

有关在数据共享中创建实体化视图的更多信息，请参阅[在 Amazon Redshift 数据共享中使用视图](https://docs.aws.amazon.com/redshift/latest/dg/datashare-views)，其中包含多个查询示例。

## 对实体化视图或基表的 DDL 更新
<a name="materialized-view-ddl"></a>

在 Amazon Redshift 中使用实体化视图时，请遵循以下有关对实体化视图或基表进行的数据定义语言 (DDL) 更新的使用说明。
+ 您可以向基表添加列，而不会影响引用该基表的任何实体化视图。
+ 某些操作可能会使实体化视图处于根本无法刷新的状态。例如，重命名或删除列、更改列类型、更改架构名称等此类操作。可以查询此类实体化视图，但不能对其进行刷新。在此情况下，必须删除并重新创建实体化视图。
+ 通常，无法更改实体化视图的定义（其 SQL 语句）。
+ 无法重命名实体化视图。

## 限制
<a name="mv_CREATE_MATERIALIZED_VIEW-limitations"></a>

您无法定义一个引用或包括以下任何内容的实体化视图：
+ 标准视图或系统表和视图。
+ 临时表。
+ 用户定义的函数。
+ ORDER BY、LIMIT 或 OFFSET 子句。
+ 对基表的后期绑定引用。换句话说，在实体化视图的定义 SQL 查询中引用的任何基表或相关列必须存在且必须有效。
+ 仅领导节点函数：CURRENT\$1SCHEMA、CURRENT\$1SCHEMAS、HAS\$1DATABASE\$1PRIVILEGE、HAS\$1SCHEMA\$1PRIVILEGE、HAS\$1TABLE\$1PRIVILEGE。
+ 当实体化视图定义包含可变函数或外部 schema 时，不能使用 AUTO REFRESH YES 选项。在一个实体化视图上定义另一个实体化视图时，也不能使用它。
+ 您不必在实体化视图上手动运行 [ANALYZE](r_ANALYZE.md)。该分析目前只通过 AUTO ANALYZE 发生。有关更多信息，请参阅 [分析表](t_Analyzing_tables.md)。
+ 受 RLS 保护或受 DDM 保护的表。
+ 从远程数据共享集群创建实体化视图，不支持对其它实体化视图、Spectrum 表、在不同 Redshift 集群中定义的表以及 UDF 的引用。从本地（生产者）集群创建实体化视图支持这些引用。

## 示例
<a name="mv_CREATE_MARTERIALIZED_VIEW_examples"></a>

以下示例从三个联接和聚合的基表创建实体化视图。每个行均代表一个类别以及已售出的票数。查询 tickets\$1mv 实体化视图时，直接在 tickets\$1mv 实体化视图中访问预计算的数据。

```
CREATE MATERIALIZED VIEW tickets_mv AS
    select   catgroup,
    sum(qtysold) as sold
    from     category c, event e, sales s
    where    c.catid = e.catid
    and      e.eventid = s.eventid
    group by catgroup;
```

以下示例创建一个类似于上一个示例的实体化视图，并使用聚合函数 MAX()。

```
CREATE MATERIALIZED VIEW tickets_mv_max AS
    select   catgroup,
    max(qtysold) as sold
    from     category c, event e, sales s
    where    c.catid = e.catid
    and      e.eventid = s.eventid
    group by catgroup;

SELECT name, state FROM STV_MV_INFO;
```

以下示例使用 UNION ALL 子句联接 Amazon Redshift `public_sales` 表和 Redshift Spectrum `spectrum.sales` 表来创建实体化视图 `mv_sales_vw`。有关适用于 Amazon Redshift Spectrum 的 CREATE EXTERNAL TABLE 命令的信息，请参阅[CREATE EXTERNAL TABLE](r_CREATE_EXTERNAL_TABLE.md)。Redshift Spectrum 外部表引用 Amazon S3 上的数据。

```
CREATE MATERIALIZED VIEW mv_sales_vw as
select salesid, qtysold, pricepaid, commission, saletime from public.sales
union all
select salesid, qtysold, pricepaid, commission, saletime from spectrum.sales
```

以下示例根据联合查询外部表创建实体化视图 `mv_fq`。有关联合查询的信息，请参阅 [CREATE EXTERNAL SCHEMA](r_CREATE_EXTERNAL_SCHEMA.md)。

```
CREATE MATERIALIZED VIEW mv_fq as select firstname, lastname from apg.mv_fq_example;

select firstname, lastname from mv_fq;
 firstname | lastname
-----------+----------
 John      | Day
 Jane      | Doe
(2 rows)
```

以下示例显示了实体化视图的定义。

```
SELECT pg_catalog.pg_get_viewdef('mv_sales_vw'::regclass::oid, true);

pg_get_viewdef
---------------------------------------------------
create materialized view mv_sales_vw as select a from t;
```

 以下示例显示了如何在实体化视图定义中设置 AUTO REFRESH 以及如何指定 DISTSTYLE。首先，创建一个简单的基表。

```
CREATE TABLE baseball_table (ball int, bat int);
```

然后，创建实体化视图。

```
CREATE MATERIALIZED VIEW mv_baseball DISTSTYLE ALL AUTO REFRESH YES AS SELECT ball AS baseball FROM baseball_table;
```

现在，您就可以查询 mv\$1baseball 实体化视图了。要检查是否对实体化视图开启了 AUTO REFRESH，请参阅 [STV\$1MV\$1INFO](r_STV_MV_INFO.md)。

以下示例创建了一个实体化视图，该视图引用了另一个数据库中的源表。它假设包含源表的数据库 database\$1A 与您在 database\$1B 中创建的实体化视图位于同一个集群或工作组中。（您可以用自己的数据库替换示例中的数据库。） 首先，在 database\$1A 中创建一个名为 *cities* 的表，其中包含 *cityname* 列。将该列的数据类型设为 VARCHAR。创建源表后，在 database\$1B 中运行以下命令，以创建其源为 *cities* 表的实体化视图。确保在 FROM 子句中指定源表的数据库和架构：

```
CREATE MATERIALIZED VIEW cities_mv AS
SELECT  cityname
FROM    database_A.public.cities;
```

查询您创建的实体化视图。该查询检索原始源为 database\$1A 中的 *cities* 表的记录：

```
select * from cities_mv;
```

当您运行 SELECT 语句时，*cities\$1mv* 会返回记录。只有在运行 REFRESH 语句时，才会刷新源表中的记录。另请注意，您不能直接在实体化视图中更新记录。有关刷新实体化视图中的数据的信息，请参阅[REFRESH MATERIALIZED VIEW](materialized-view-refresh-sql-command.md)。

有关实体化视图概述以及用于刷新和删除实体化视图的 SQL 命令的详细信息，请参阅以下主题：
+ [Amazon Redshift 中的实体化视图](materialized-view-overview.md)
+ [REFRESH MATERIALIZED VIEW](materialized-view-refresh-sql-command.md)
+ [DROP MATERIALIZED VIEW](materialized-view-drop-sql-command.md)

# CREATE MODEL
<a name="r_CREATE_MODEL"></a>

**Topics**
+ [先决条件](#r_create_model_prereqs)
+ [所需的权限](#r_simple_create_model-privileges)
+ [成本控制](#r_create_model_cost)
+ [Full CREATE MODEL](#r_full_create_model)
+ [参数](#r_create_model_parameters)
+ [使用说明](r_create_model_usage_notes.md)
+ [使用案例](r_create_model_use_cases.md)

## 先决条件
<a name="r_create_model_prereqs"></a>

在使用 CREATE MODEL 语句之前，请完成 [用于使用 Amazon Redshift ML 的集群设置](getting-started-machine-learning.md#cluster-setup) 中的先决条件。下面简要概述了这些先决条件。
+ 使用 AWS 管理控制台或 AWS 命令行界面 (AWS CLI) 创建 Amazon Redshift 集群。
+ 在创建集群时附加 AWS Identity and Access Management (IAM) policy。
+ 要支持 Amazon Redshift 和 SageMaker AI 代入角色以便与其它服务交互，请向 IAM 角色添加相应的信任策略。

有关 IAM 角色、信任策略和其他先决条件的详细信息，请参阅[用于使用 Amazon Redshift ML 的集群设置](getting-started-machine-learning.md#cluster-setup)。

您可以在下面找到 CREATE MODEL 语句的不同使用案例。
+ [简单 CREATE MODEL](r_create_model_use_cases.md#r_simple_create_model)
+ [根据用户指导创建模型](r_create_model_use_cases.md#r_user_guidance_create_model)
+ [带有 AUTO OFF 的 CREATE XGBoost 模型](r_create_model_use_cases.md#r_auto_off_create_model)
+ [自带模型 (BYOM) – 本地推理](r_create_model_use_cases.md#r_byom_create_model)
+ [自带模型 (BYOM) – 远程推理](r_create_model_use_cases.md#r_byom_create_model_remote)
+ [带有 K-MANES 的 CREATE MODEL](r_create_model_use_cases.md#r_k-means_create_model)
+ [Full CREATE MODEL](#r_full_create_model)

## 所需的权限
<a name="r_simple_create_model-privileges"></a>

以下是 CREATE MODEL 所需的权限：
+ Superuser
+ 具有 CREATE MODEL 权限的用户
+ 具有 GRANT CREATE MODEL 权限的角色

## 成本控制
<a name="r_create_model_cost"></a>

 Amazon Redshift ML 使用现有集群资源创建预测模型，因此您无需支付额外费用。但是，如果您需要调整集群的大小或训练模型，则可能需要支付额外费用。Amazon Redshift ML 使用 Amazon SageMaker AI 来训练模型，这确实会产生额外的关联费用。可以通过多种方法控制额外成本，例如，限制训练可花费的最长时间，或限制用于训练模型的训练样本数量。有关更多信息，请参阅[使用 Amazon Redshift ML 的成本](https://docs.aws.amazon.com/redshift/latest/dg/cost.html)。

## Full CREATE MODEL
<a name="r_full_create_model"></a>

下面总结了完整的 CREATE MODEL 语法的基本选项。

### Full CREATE MODEL 语法
<a name="r_auto_off-create-model-synposis"></a>

以下是 CREATE MODEL 语句的完整语法。

**重要**  
使用 CREATE MODEL 语句创建模型时，请按照以下语法中关键词的顺序进行操作。

```
CREATE MODEL model_name
FROM { table_name | ( select_statement )  | 'job_name' }
[ TARGET column_name ]
FUNCTION function_name [ ( data_type [, ...] ) ] 
[ RETURNS data_type ] 
  -- supported only for BYOM
[ SAGEMAKER 'endpoint_name'[:'model_name']] 
  -- supported only for BYOM remote inference
IAM_ROLE { default | 'arn:aws:iam::<account-id>:role/<role-name>' }
[ AUTO ON / OFF ]
  -- default is AUTO ON
[ MODEL_TYPE { XGBOOST | MLP | LINEAR_LEARNER | KMEANS | FORECAST } ]
  -- not required for non AUTO OFF case, default is the list of all supported types
  -- required for AUTO OFF
[ PROBLEM_TYPE ( REGRESSION | BINARY_CLASSIFICATION | MULTICLASS_CLASSIFICATION ) ]
  -- not supported when AUTO OFF
[ OBJECTIVE ( 'MSE' | 'Accuracy' | 'F1' | 'F1_Macro' | 'AUC' |
             'reg:squarederror' | 'reg:squaredlogerror'| 'reg:logistic'|
             'reg:pseudohubererror' | 'reg:tweedie' | 'binary:logistic' | 'binary:hinge',
             'multi:softmax' | 'RMSE' | 'WAPE' | 'MAPE' | 'MASE' | 'AverageWeightedQuantileLoss' ) ]
  -- for AUTO ON: first 5 are valid
  -- for AUTO OFF: 6-13 are valid
  -- for FORECAST: 14-18 are valid
[ PREPROCESSORS 'string' ]
  -- required for AUTO OFF, when it has to be 'none'
  -- optional for AUTO ON
[ HYPERPARAMETERS { DEFAULT | DEFAULT EXCEPT ( Key 'value' (,...) ) } ]
  -- support XGBoost hyperparameters, except OBJECTIVE
  -- required and only allowed for AUTO OFF
  -- default NUM_ROUND is 100
  -- NUM_CLASS is required if objective is multi:softmax (only possible for AUTO OFF)
 [ SETTINGS (
   S3_BUCKET 'amzn-s3-demo-bucket',  |
    -- required
  TAGS 'string', |
    -- optional
  KMS_KEY_ID 'kms_string', |
    -- optional
  S3_GARBAGE_COLLECT on / off, |
    -- optional, defualt is on.
  MAX_CELLS integer, |
    -- optional, default is 1,000,000
  MAX_RUNTIME integer (, ...) |
    -- optional, default is 5400 (1.5 hours)
  HORIZON integer, |
    -- required if creating a forecast model
  FREQUENCY integer, |
    -- required if creating a forecast model
  PERCENTILES string, |
    -- optional if creating a forecast model
  MAX_BATCH_ROWS integer -- optional for BYOM remote inference
    ) ]
```

## 参数
<a name="r_create_model_parameters"></a>

model\$1name  
模型的名称。schema 中的模型名称必须是唯一的。

FROM \$1 *table\$1name* \$1 ( *select\$1query* ) \$1 *'job\$1name'*\$1  
指定训练数据的 table\$1name 或查询。它们可以是系统中的现有表，也可以是用括号（即 ()）括起来的兼容 Amazon RedShift 的 SELECT 查询。查询结果中必须至少有两列。

TARGET *column\$1name*  
成为预测目标的列的名称。FROM 子句中必须存在该列。

FUNCTION *function\$1name* ( *data\$1type* [, ...] )  
要创建的函数的名称以及输入参数的数据类型。您可以提供数据库中架构的架构名称而不是函数名称。

RETURNS *data\$1type*  
要从模型的函数返回的数据类型。返回的 `SUPER` 数据类型仅适用于具有远程推理的 BYOM。

SAGEMAKER *'endpoint\$1name'*[:*'model\$1name'*]  
Amazon SageMaker AI 端点的名称。如果端点名称指向多模型端点，请添加要使用的模型名称。端点必须与 Amazon Redshift 集群托管于同一 AWS 区域。

IAM\$1ROLE \$1 default \$1 'arn:aws:iam::<account-id>:role/<role-name>'\$1  
 使用默认关键字让 Amazon Redshift 使用 IAM 角色，该角色设置为默认值并在 CREATE MODEL 命令运行时与集群关联。或者，您可以指定 IAM 角色的 ARN 来使用该角色。

[ AUTO ON / OFF ]  
 打开或关闭预处理器、算法和超参数选择的 CREATE MODEL 自动发现。在创建预测模型时指定 On 表示使用 AutoPredictor，其中 Amazon Forecast 会将算法的最佳组合应用于数据集中的每个时间序列。

 *MODEL\$1TYPE \$1 XGBOOST \$1 MLP \$1 LINEAR\$1LEARNER \$1 KMEANS \$1 FORECAST \$1*   
（可选）指定模型类型。您可以指定是否要训练特定模型类型的模型，如 XGBoost、多层感知机（MLP）、KMEANS 或线性学习器，这些都是 Amazon SageMaker AI Autopilot 支持的算法。如果未指定参数，则在训练期间搜索所有受支持的模型类型，以找到最佳模型。您还可以在 Redshift ML 中创建预测模型，以创建准确的时间序列预测。

 *PROBLEM\$1TYPE ( REGRESSION \$1 BINARY\$1CLASSIFICATION \$1 MULTICLASS\$1CLASSIFICATION )*   
（可选）指定问题类型。如果您知道问题类型，您可以将 Amazon Redshift 限制为仅搜索该特定模型类型的最佳模型。如果未指定此参数，则会在训练期间根据您的数据发现问题类型。

OBJECTIVE ( 'MSE' \$1 'Accuracy' \$1 'F1' \$1 'F1Macro' \$1 'AUC' \$1 'reg:squarederror' \$1 'reg:squaredlogerror' \$1 'reg:logistic' \$1 'reg:pseudohubererror' \$1 'reg:tweedie' \$1 'binary:logistic' \$1 'binary:hinge' \$1 'multi:softmax' \$1 'RMSE' \$1 'WAPE' \$1 'MAPE' \$1 'MASE' \$1 'AverageWeightedQuantileLoss' )  
（可选）指定用于测量机器学习系统预测质量的目标指标的名称。此指标在训练过程中进行了优化，以便从数据中为模型参数值提供最佳估计值。如果未明确指定指标，则默认行为是自动使用 MSE：用于回归，F1：用于二进制分类，精度：用于多类分类。有关目标的更多信息，请参阅《Amazon SageMaker AI API 参考》**中的 [AutoMLJobObjective](https://docs.aws.amazon.com//sagemaker/latest/APIReference/API_AutoMLJobObjective.html) 以及 XGBOOST 文档中的 [Learning task parameters](https://xgboost.readthedocs.io/en/latest/parameter.html#learning-task-parameters)。值 RMSE、WAPE、MAPE、MASE 和 AverageWeightedQuantileLoss 仅适用于预测模型。有关更多信息，请参阅 [CreateAutoPredictor](https://docs.aws.amazon.com/forecast/latest/dg/API_CreateAutoPredictor.html#forecast-CreateAutoPredictor-request-OptimizationMetric) API 操作。

 *PREPROCESSORS 'string'*  
（可选）将预处理器的某些组合指定为某些列的集合。格式是 columnSet 的列表，以及要应用于每组列的适当转换。Amazon Redshift 将特定转换器列表中的所有转换器应用于相应 ColumnSet 中的所有列。例如，要将带有 Imputer 的 OneHotEncoder 应用于列 t1 和 t2，请使用下面的示例命令。  

```
CREATE MODEL customer_churn
FROM customer_data
TARGET 'Churn'
FUNCTION predict_churn
IAM_ROLE { default | 'arn:aws:iam::<account-id>:role/<role-name>' }
PROBLEM_TYPE BINARY_CLASSIFICATION
OBJECTIVE 'F1'
PREPROCESSORS '[
...
  {"ColumnSet": [
      "t1",
      "t2"
    ],
    "Transformers": [
      "OneHotEncoder",
      "Imputer"
    ]
  },
  {"ColumnSet": [
      "t3"
    ],
    "Transformers": [
      "OneHotEncoder"
    ]
  },
  {"ColumnSet": [
      "temp"
    ],
    "Transformers": [
      "Imputer",
      "NumericPassthrough"
    ]
  }
]'
SETTINGS (
  S3_BUCKET 'amzn-s3-demo-bucket'
)
```

HYPERPARAMETERS \$1 DEFAULT \$1 DEFAULT EXCEPT ( key ‘value’ (,..) ) \$1  
指定默认的 XGBoost 参数是被使用还是被用户指定的值覆盖。值必须用单引号引起来。以下是 XGBoost 的参数示例及其默认值。      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_CREATE_MODEL.html)

SETTINGS ( S3\$1BUCKET *'amzn-s3-demo-bucket'*, \$1 TAGS 'string', \$1 KMS\$1KEY\$1ID *'kms\$1string' *, \$1 S3\$1GARBAGE\$1COLLECT on / off, \$1 MAX\$1CELLS integer , \$1 MAX\$1RUNTIME (,...) , \$1 HORIZON integer, \$1 FREQUENCY forecast\$1frequency, \$1 PERCENTILES array of strings )  
S3\$1BUCKET 子句指定用于存储中间结果的 Amazon S3 位置。  
（可选）TAGS 参数是以逗号分隔的键值对列表，可用于标记在 Amazon SageMaker AI 和 Amazon Forecast 中创建的资源。标签有助于组织资源和分配成本。键/值对中的值是可选的，因此您可以使用格式 `key=value` 或只是通过创建键来创建标签。有关 Amazon Redshift 中的标签的更多信息，请参阅[标记概述](https://docs.aws.amazon.com/redshift/latest/mgmt/amazon-redshift-tagging.html)。  
（可选）KMS\$1KEY\$1ID 指定 Amazon Redshift 是否将服务器端加密与 AWS KMS 键结合使用来保护静态数据。传输中的数据由安全套接字层 (SSL) 保护。  
（可选）S3\$1GARBAGE\$1COLLECT \$1 ON \$1 OFF \$1 指定 Amazon Redshift 是否对用于训练模型的生成数据集和模型执行垃圾回收。如果设置为 OFF，则用于训练模型的生成数据集和模型将保留在 Amazon S3 中，并可用于其他目的。如果设置为 ON，则 Amazon Redshift 会在训练完成后删除 Amazon S3 中的构件。默认为 ON。  
（可选）MAX\$1CELLS 指定训练数据中的单元格的数量。此值是记录数（在训练查询或表中）乘以列数的乘积。默认值是 1000000。  
（可选）MAX\$1RUNTIME 指定最长训练时间。根据数据集的大小，训练任务通常可以更早完成。这将指定训练所需的最长时间。默认值为 5400（90 分钟）。  
HORIZON 指定了预测模型可以返回的最大预测数。模型一旦经过训练，就无法更改此整数。如果训练预测模型，则此参数是必需的。  
FREQUENCY 指定了您希望预测以时间为单位的粒度。可用的选项为 `Y | M | W | D | H | 30min | 15min | 10min | 5min | 1min`。如果训练预测模型，则此参数是必需的。  
（可选）PERCENTILES 是一个以逗号分隔的字符串，指定用于训练预测器的预测类型。预测类型可以是从 0.01 到 0.99 的分位数，增量为 0.01 或更高。您也可以使用均值指定均值预测。您最多可以指定五种预测类型。

 MAX\$1BATCH\$1ROWS *整数*   
（可选）Amazon Redshift 在单个批处理请求中为单个 SageMaker AI 调用发送的最大行数。只有具有远程推理功能的 BYOM 才支持此项。此参数的最小值为 1。最大值为 `INT_MAX`，即 2147483647。仅当输入和返回的数据类型均为 *SUPER* 时，才需要此参数。默认值为 `INT_MAX`，即 2147483647。

# 使用说明
<a name="r_create_model_usage_notes"></a>

使用 CREATE MODEL 时，请注意以下事项：
+ CREATE MODEL 语句在异步模式下运行，并在将训练数据导出到 Amazon S3 时返回。Amazon SageMaker AI 中的其余训练步骤将在后台进行。当训练正在进行时，相应的推理函数可见，但无法运行。您可以查询 [STV\$1ML\$1MODEL\$1INFO](r_STV_ML_MODEL_INFO.md) 以查看训练状态。
+ 预设情况下，在 Auto 模型中，训练最多可以在后台运行 90 分钟，并且可以延长。要取消训练，只需运行 [DROP MODEL](r_DROP_MODEL.md) 命令。
+ 您用于创建模型的 Amazon Redshift 集群和用于暂存训练数据和模型构件的 Amazon S3 桶必须位于同一 AWS 区域。
+ 在模型训练期间，Amazon Redshift 和 SageMaker AI 将中间构件存储在您提供的 Amazon S3 存储桶中。默认情况下，Amazon Redshift 会在 CREATE MODEL 操作结束时执行垃圾回收。Amazon Redshift 从 Amazon S3 中删除这些对象。要在 Amazon S3 上保留这些构件，请设置 S3\$1GARBAGE COLLECT OFF 选项。
+ 您必须在 FROM 子句中提供的训练数据中至少使用 500 行。
+ 使用 CREATE MODEL 语句时，最多只能在 FROM \$1 table\$1name \$1 ( select\$1query ) \$1 子句中指定 256 个功能（输入）列。
+ 对于 AUTO ON，您可以用作训练集的列类型包括 SMALLINT、INTEGER、BIGINT、DECIMAL、REAL、DOUBLE、BOOLEAN、CHAR、VARCHAR、DATE、TIME、TIMETZ、TIMESTAMP 和 TIMESTAMPTZ。对于 AUTO OFF，您可以用作训练集的列类型包括 SMALLINT、INTEGER、BIGINT、DECIMAL、REAL、DOUBLE 和 BOOLEAN。
+ 不可使用 DECIMAL、DATE、TIME、TIMETZ、TIMESTAMP、TIMESTAMPTZ、GEOMETRY、GEOGRAPHY、HLLSKETCH、SUPER 或 VARBYTE 作为目标列类型。
+ 要提高模型精度，请执行以下操作之一：
  + 在 FROM 子句中指定训练数据时，在 CREATE MODEL 命令中添加尽可能多的相关列。
  + 对于 MAX\$1RUNTIME 和 MAX\$1CELLS，请使用较大的值。此参数的值越大，就会增加训练模型的成本。
+ 一旦计算训练数据并导出到 Amazon S3 桶后，CREATE MODEL 语句执行就会立即返回。在此之后，您可以使用 SHOW MODEL 命令检查训练的状态。当在后台训练的模型失败时，可以使用 SHOW MODEL 检查错误。您无法重试失败的模型。使用 DROP MODEL 移除失败的模型并重新创建新模型。有关 SHOW MODEL 的更多信息，请参阅[SHOW MODEL](r_SHOW_MODEL.md)。
+ 本地 BYOM 支持的模型类型与 Amazon Redshift ML 为非 BYOM 案例支持的模型类型相同。Amazon Redshift 支持普通的 XGBoost（使用 XGBoost 版本 1.0 或更高版本），没有预处理器的 KMEANS 模型，以及经过 Amazon SageMaker AI Autopilot 训练的 XGBOOST/MLP/线性学习器模型。它支持后者与 Autopilot 指定的预处理器，该预处理器也由 Amazon SageMaker AI Neo 提供支持。
+ 如果 Amazon Redshift 集群增强了为虚拟私有云（VPC）启用的路由，请确保为集群所在的 VPC 创建 Amazon S3 VPC 端点和 SageMaker AI VPC 端点。这样做使得流量可以在 CREATE MODEL 期间通过您的 VPC 在服务之间运行。有关更多信息，请参阅 [SageMaker AI Clarify Job Amazon VPC Subnets and Security Groups](https://docs.aws.amazon.com/sagemaker/latest/dg/clarify-vpc.html#clarify-vpc-job)。

# 使用案例
<a name="r_create_model_use_cases"></a>

以下使用案例演示了如何使用 CREATE MODEL 来满足您的需求。

## 简单 CREATE MODEL
<a name="r_simple_create_model"></a>

下面总结了 CREATE MODEL 语法的基本选项。

### 简单的 CREATE MODEL 语法
<a name="r_simple-create-model-synposis"></a>

```
CREATE MODEL model_name
FROM { table_name | ( select_query ) }
TARGET column_name
FUNCTION prediction_function_name
IAM_ROLE { default }
SETTINGS (
  S3_BUCKET 'amzn-s3-demo-bucket',
  [ MAX_CELLS integer ]
)
```

### 简单 CREATE MODEL 参数
<a name="r_simple-create-model-parameters"></a>

 *model\$1name*   
模型的名称。schema 中的模型名称必须是唯一的。

FROM \$1 *table\$1name* \$1 ( *select\$1query* ) \$1  
指定训练数据的 table\$1name 或查询。它们可以是系统中的现有表，也可以是用括号（即 ()）括起来的兼容 Amazon RedShift 的 SELECT 查询。查询结果中必须至少有两列。

TARGET *column\$1name*  
成为预测目标的列的名称。FROM 子句中必须存在该列。

FUNCTION *prediction\$1function\$1name*   
一个值，它指定由 CREATE MODEL 生成并用于使用此模型进行预测的 Amazon Redshift 机器学习函数的名称。该函数在与模型对象相同的 schema 中创建，并且可以重载。  
Amazon Redshift 机器学习支持模型，例如用于回归和分类的 Xtreme Gradient Boosted 树 (XGBoost) 模型。

IAM\$1ROLE \$1 default \$1 'arn:aws:iam::<account-id>:role/<role-name>' \$1  
 使用默认关键字让 Amazon Redshift 使用设置为默认值并在 CREAT MODEL 命令运行时与集群关联的 IAM 角色。或者，您可以指定 IAM 角色的 ARN 来使用该角色。

 *S3\$1BUCKET *'amzn-s3-demo-bucket'**  
您之前创建的 Amazon S3 存储桶的名称，该存储桶用于在 Amazon Redshift 和 SageMaker AI 之间共享训练数据和构件。在卸载训练数据之前，Amazon Redshift 会在此桶中创建一个子文件夹。训练完成后，Amazon Redshift 会删除创建的子文件夹及其内容。

MAX\$1CELLS 整数   
要从 FROM 子句中导出的最大单元格数。默认值为 1000000。  
单元格数量是训练数据中的行数（由 FROM 子句表或查询生成）乘以列数的乘积。如果训练数据中的单元格数大于 max\$1cells 参数指定的单元格数，则 CREATE MODEL 会缩小 FROM 子句训练数据的取样，以减小 MAX\$1CELLS 下面的训练集的大小。允许更大的训练数据集可以产生更高的精度，但也意味着模型需要更长的时间来训练并且成本更高。  
有关使用 Amazon Redshift 的成本的信息，请参阅[使用 Amazon Redshift ML 的成本](cost.md)。  
有关与各种单元格数量相关的成本免费试用详细信息，请参阅 [Amazon Redshift 定价](https://aws.amazon.com/redshift/pricing)。

## 根据用户指导创建模型
<a name="r_user_guidance_create_model"></a>

除了 [简单 CREATE MODEL](#r_simple_create_model) 中所述的选项之外，您还可以在下面找到 CREATE MODEL 选项的描述。

预设情况下，CREATE MODEL 会搜索特定数据集的预处理和模型的最佳组合。您可能需要对模型进行额外的控制或引入其他领域知识（例如问题类型或目标）。在客户流失情况下，如果结果“客户不活跃”很少，则 F1 目标通常优先于精度目标。由于高精度模型可能会始终预测“客户处于活动状态”，因此可以实现高精度，但商业价值却很少。有关 F1 目标的信息，请参阅《Amazon SageMaker AI API 参考》**中的 [AutoMLJobObjective](https://docs.aws.amazon.com//sagemaker/latest/APIReference/API_AutoMLJobObjective.html)。

然后，CREATE MODEL 将遵循您对目标等指定方面的建议。同时，CREATE MODEL 会自动发现最佳预处理器和最佳超参数。

### 使用用户指导语法创建模型
<a name="r_user_guidance-create-model-synposis"></a>

CREATE MODEL 在您可以指定的方面以及 Amazon Redshift 自动发现的方面提供了更大的灵活度。

```
CREATE MODEL model_name
FROM { table_name | ( select_statement ) }
TARGET column_name
FUNCTION function_name
IAM_ROLE { default }
[ MODEL_TYPE { XGBOOST | MLP | LINEAR_LEARNER} ]
[ PROBLEM_TYPE ( REGRESSION | BINARY_CLASSIFICATION | MULTICLASS_CLASSIFICATION ) ]
[ OBJECTIVE ( 'MSE' | 'Accuracy' | 'F1' | 'F1Macro' | 'AUC') ]
SETTINGS (
  S3_BUCKET 'amzn-s3-demo-bucket', |
  S3_GARBAGE_COLLECT { ON | OFF }, |
  KMS_KEY_ID 'kms_key_id', |
  MAX_CELLS integer, |
  MAX_RUNTIME integer (, ...)
)
```

### 使用用户指导参数创建模型
<a name="r_user_guidance-create-model-parameters"></a>

 *MODEL\$1TYPE \$1 XGBOOST \$1 MLP \$1 LINEAR\$1LEARNER \$1*   
（可选）指定模型类型。您可以指定是否要训练特定模型类型的模型，如 XGBoost、多层感知机（MLP）或线性学习器，这些是 Amazon SageMaker AI Autopilot 支持的所有算法。如果未指定参数，则在训练期间搜索所有受支持的模型类型，以找到最佳模型。

 *PROBLEM\$1TYPE ( REGRESSION \$1 BINARY\$1CLASSIFICATION \$1 MULTICLASS\$1CLASSIFICATION )*   
（可选）指定问题类型。如果您知道问题类型，您可以将 Amazon Redshift 限制为仅搜索该特定模型类型的最佳模型。如果未指定此参数，则会在训练期间根据您的数据发现问题类型。

OBJECTIVE ( 'MSE' \$1 'Accuracy' \$1 'F1' \$1 'F1Macro' \$1 'AUC')  
（可选）指定用于测量机器学习系统预测质量的目标指标的名称。此指标在训练过程中进行了优化，以便从数据中为模型参数值提供最佳估计值。如果未明确指定指标，则默认行为是自动使用 MSE：用于回归，F1：用于二进制分类，精度：用于多类分类。有关目标的更多信息，请参阅《Amazon SageMaker AI API 参考》**中的 [AutoMLJobObjective](https://docs.aws.amazon.com//sagemaker/latest/APIReference/API_AutoMLJobObjective.html)。

MAX\$1CELLS 整数   
（可选）指定训练数据中的单元格的数量。此值是记录数（在训练查询或表中）乘以列数的乘积。默认值为 1000000。

MAX\$1RUNTIME 整数   
（可选）指定最长训练时间。根据数据集的大小，训练任务通常可以更早完成。这将指定训练所需的最长时间。默认值为 5400（90 分钟）。

S3\$1GARBAGE\$1COLLECT \$1 ON \$1 OFF \$1  
（可选）指定 Amazon Redshift 是否对用于训练模型的生成数据集和模型执行垃圾回收。如果设置为 OFF，则用于训练模型的生成数据集和模型将保留在 Amazon S3 中，并可用于其他目的。如果设置为 ON，则 Amazon Redshift 会在训练完成后删除 Amazon S3 中的构件。默认为 ON。

KMS\$1KEY\$1ID 'kms\$1key\$1id'  
（可选）指定 Amazon Redshift 是否将服务器端加密与 AWS KMS 键结合使用来保护静态数据。传输中的数据由安全套接字层 (SSL) 保护。

 *PREPROCESSORS 'string'*  
（可选）将预处理器的某些组合指定为某些列的集合。格式是 columnSet 的列表，以及要应用于每组列的适当转换。Amazon Redshift 将特定转换器列表中的所有转换器应用于相应 ColumnSet 中的所有列。例如，要将带有 Imputer 的 OneHotEncoder 应用于列 t1 和 t2，请使用下面的示例命令。  

```
CREATE MODEL customer_churn
FROM customer_data
TARGET 'Churn'
FUNCTION predict_churn
IAM_ROLE { default | 'arn:aws:iam::<account-id>:role/<role-name>' }
PROBLEM_TYPE BINARY_CLASSIFICATION
OBJECTIVE 'F1'
PREPROCESSORS '[
...
{"ColumnSet": [
    "t1",
    "t2"
  ],
  "Transformers": [
    "OneHotEncoder",
    "Imputer"
  ]
},
{"ColumnSet": [
    "t3"
  ],
  "Transformers": [
    "OneHotEncoder"
  ]
},
{"ColumnSet": [
    "temp"
  ],
  "Transformers": [
    "Imputer",
    "NumericPassthrough"
  ]
}
]'
SETTINGS (
S3_BUCKET 'amzn-s3-demo-bucket'
)
```

Amazon Redshift 支持以下转换器：
+ OneHotEncoder – 通常用于将离散值编码为具有一个非零值的二进制向量。该转换器适用于许多机器学习模型。
+ OrdinalEncoder – 将离散值编码为单个整数。该转换器适用于特定机器学习模型，如 MLP 和线性学习器。
+ NumericPassthrough – 将输入按原样传递到模型中。
+ Imputer – 填充缺少的值，而不是数字 (NaN) 值。
+ ImputerWithIndicator – 填充缺少值和 NaN 值。此转换器器还会创建一个指示器，指示是否有任何值缺失以及被填充。
+ Normalizer – 标准化值，这可以提高许多机器学习算法的性能。
+ DateTimeVectorizer – 创建向量嵌入，表示可在机器学习模型中使用的日期时间数据类型列。
+ PCA – 将数据投影到低维空间中，以减少功能数量，同时保留尽可能多的信息。
+ StandardScaler – 通过去除平均值并缩放至单位方差来标准化功能。
+ MinMax – 通过将每个功能缩放至给定范围来转换功能。

Amazon Redshift ML 存储经过训练的转换器，并将其作为预测查询的一部分自动应用。在从模型生成预测时，您不需要指定它们。

## 带有 AUTO OFF 的 CREATE XGBoost 模型
<a name="r_auto_off_create_model"></a>

AUTO OFF CREATE MODEL 的目标通常与默认的 CREATE MODEL 不同。

作为高级用户，在训练这些模型时便已经知道所需的模型类型和要使用的超参数，因此，可以使用带有 AUTO OFF 的 CREATE MODEL 关闭预处理器和超参数的 CREATE MODEL 自动发现。为此，您可以显式指定模型类型。XGBoost 目前是 AUTO 被设置为 OFF 时支持的唯一模型类型。您可以指定超参数。Amazon Redshift 对您指定的任何超参数使用默认值。

### 带有 AUTO OFF 语法的 CREATE XGBoost 模型
<a name="r_auto_off-create-model-synposis"></a>

```
CREATE MODEL model_name
FROM { table_name | (select_statement ) }
TARGET column_name
FUNCTION function_name
IAM_ROLE { default }
AUTO OFF
MODEL_TYPE XGBOOST
OBJECTIVE { 'reg:squarederror' | 'reg:squaredlogerror' | 'reg:logistic' |
            'reg:pseudohubererror' | 'reg:tweedie' | 'binary:logistic' | 'binary:hinge' |
            'multi:softmax' | 'rank:pairwise' | 'rank:ndcg' }
HYPERPARAMETERS DEFAULT EXCEPT (
    NUM_ROUND '10',
    ETA '0.2',
    NUM_CLASS '10',
    (, ...)
)
PREPROCESSORS 'none'
SETTINGS (
  S3_BUCKET 'amzn-s3-demo-bucket', |
  S3_GARBAGE_COLLECT { ON | OFF }, |
  KMS_KEY_ID 'kms_key_id', |
  MAX_CELLS integer, |
  MAX_RUNTIME integer (, ...)
)
```

### 使用 AUTO OFF 参数创建 XGBoost 模型
<a name="r_auto_off-create-model-parameters"></a>

 *AUTO OFF*   
关闭预处理器、算法和超参数选择的 CREATE MODEL 自动发现。

MODEL\$1TYPE XGBOOST  
指定使用 XGBOOST 来训练模型。

OBJECTIVE str  
指定算法识别的目标。Amazon Redshift 支持 reg:squarederror、reg:squaredlogerror、reg:logistic、reg:pseudohubererror、reg:tweedie、binary:logistic、binary:hinge、multi:softmax。有关这些目标的更多信息，请参阅 XGBoost 文档中的[学习任务参数](https://xgboost.readthedocs.io/en/latest/parameter.html#learning-task-parameters)。

HYPERPARAMETERS \$1 DEFAULT \$1 DEFAULT EXCEPT ( key ‘value’ (,..) ) \$1  
指定默认的 XGBoost 参数是被使用还是被用户指定的值覆盖。值必须用单引号引起来。以下是 XGBoost 的参数示例及其默认值。      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_create_model_use_cases.html)

以下示例为 XGBoost 准备数据。

```
DROP TABLE IF EXISTS abalone_xgb;

CREATE TABLE abalone_xgb (
length_val float,
diameter float,
height float,
whole_weight float,
shucked_weight float,
viscera_weight float,
shell_weight float,
rings int,
record_number int);

COPY abalone_xgb
FROM 's3://redshift-downloads/redshift-ml/abalone_xg/'
REGION 'us-east-1'
IAM_ROLE default
IGNOREHEADER 1 CSV;
```

以下示例创建具有指定高级选项的 XGBoost 模型，如 MODEL\$1TYPE、OBJECTIVE 和 PREPROCESSORS。

```
DROP MODEL abalone_xgboost_multi_predict_age;

CREATE MODEL abalone_xgboost_multi_predict_age
FROM ( SELECT length_val,
              diameter,
              height,
              whole_weight,
              shucked_weight,
              viscera_weight,
              shell_weight,
              rings
   FROM abalone_xgb WHERE record_number < 2500 )
TARGET rings FUNCTION ml_fn_abalone_xgboost_multi_predict_age
IAM_ROLE default
AUTO OFF
MODEL_TYPE XGBOOST
OBJECTIVE 'multi:softmax'
PREPROCESSORS 'none'
HYPERPARAMETERS DEFAULT EXCEPT (NUM_ROUND '100', NUM_CLASS '30')
SETTINGS (S3_BUCKET 'amzn-s3-demo-bucket');
```

以下示例使用推断查询来预测记录编号大于 2500 的鱼的年龄。它使用从上述命令创建的函数 ml\$1fn\$1abalone\$1xgboost\$1multi\$1predict\$1age。

```
select ml_fn_abalone_xgboost_multi_predict_age(length_val,
                                                   diameter,
                                                   height,
                                                   whole_weight,
                                                   shucked_weight,
                                                   viscera_weight,
                                                   shell_weight)+1.5 as age
from abalone_xgb where record_number > 2500;
```

## 自带模型 (BYOM) – 本地推理
<a name="r_byom_create_model"></a>

Amazon Redshift ML 支持使用自带模型 (BYOM) 进行本地推理。

下面总结了 BYOM 的 CREATE MODEL 语法的选项。您可以将在 Amazon Redshift 之外训练的模型与 Amazon SageMaker AI 结合使用，以用于 Amazon Redshift 本地的数据库内推理。

### 用于本地推理的 CREATE MODEL 语法
<a name="r_local-create-model"></a>

下面介绍了用于本地推理的 CREATE MODEL 语法。

```
CREATE MODEL model_name
FROM ('job_name' | 's3_path' )
FUNCTION function_name ( data_type [, ...] )
RETURNS data_type
IAM_ROLE { default }
[ SETTINGS (
  S3_BUCKET 'amzn-s3-demo-bucket', | --required
  KMS_KEY_ID 'kms_string') --optional
];
```

Amazon Redshift 目前仅支持针对 BYOM 的预先训练的 XGBoost、MLP 和线性学习器模型。您可以使用此路径导入 SageMaker AI Autopilot 和直接在 Amazon SageMaker AI 中训练的模型，以便进行本地推理。

#### 用于本地推理的 CREATE MODEL 参数
<a name="r_local-create-model-parameters"></a>

 *model\$1name*   
模型的名称。schema 中的模型名称必须是唯一的。

FROM (*'job\$1name'* \$1 *'s3\$1path'* )  
*job\$1name* 将 Amazon SageMaker AI 作业名称用作输入。作业名称可以是 Amazon SageMaker AI 训练作业名称，也可以是 Amazon SageMaker AI Autopilot 作业名称。任务必须在拥有 Amazon Redshift 集群的相同AWS账户中创建。要查找作业名称，请启动 Amazon SageMaker AI。在**训练**下拉菜单中，选择**训练作业**。  
*'s3\$1path'* 指定创建模型时要使用的 .tar.gz 模型构件文件的 S3 位置。

FUNCTION *function\$1name* ( *data\$1type* [, ...] )  
要创建的函数的名称以及输入参数的数据类型。您可以提供 schema 名称。

RETURNS *data\$1type*  
函数返回的值的数据类型。

IAM\$1ROLE \$1 default \$1 'arn:aws:iam::<account-id>:role/<role-name>'\$1  
 使用默认关键字让 Amazon Redshift 使用 IAM 角色，该角色设置为默认值并在 CREATE MODEL 命令运行时与集群关联。  
使用 IAM 角色的 Amazon 资源名称（ARN），您的集群使用该角色进行身份验证和授权。

SETTINGS ( S3\$1BUCKET *'amzn-s3-demo-bucket'*, \$1 KMS\$1KEY\$1ID *'kms\$1string'*)  
S3\$1BUCKET 子句指定用于存储中间结果的 Amazon S3 位置。  
（可选）KMS\$1KEY\$1ID 子句指定 Amazon Redshift 是否将服务器端加密与 AWS KMS 键结合使用来保护静态数据。传输中的数据由安全套接字层 (SSL) 保护。  
有关更多信息，请参阅 [根据用户指导创建模型](#r_user_guidance_create_model)。

#### 用于本地推理的 CREATE MODEL 语法示例
<a name="r_local-create-model-example"></a>

以下示例创建之前在 Amazon Redshift 之外的 Amazon SageMaker AI 中训练过的模型。由于 Amazon Redshift ML 支持模型类型进行本地推理，因此以下 CREATE MODEL 将创建一个可在 Amazon Redshift 中本地使用的函数。您可以提供 SageMaker AI 训练作业名称。

```
CREATE MODEL customer_churn
FROM 'training-job-customer-churn-v4'
FUNCTION customer_churn_predict (varchar, int, float, float)
RETURNS int
IAM_ROLE default
SETTINGS (S3_BUCKET 'amzn-s3-demo-bucket');
```

创建模型后，您可以将函数 *customer\$1churn\$1predict* 与指定参数类型结合使用以进行预测。

## 自带模型 (BYOM) – 远程推理
<a name="r_byom_create_model_remote"></a>

Amazon Redshift ML 还支持使用自带模型 (BYOM) 进行远程推理。

下面总结了 BYOM 的 CREATE MODEL 语法的选项。

### 用于远程推理的 CREATE MODEL 语法
<a name="r_remote-create-model"></a>

下面介绍了用于远程推理的 CREATE MODEL 语法。

```
CREATE MODEL model_name 
FUNCTION function_name ( data_type [, ...] )
RETURNS data_type
SAGEMAKER 'endpoint_name'[:'model_name']
IAM_ROLE { default | 'arn:aws:iam::<account-id>:role/<role-name>' }
[SETTINGS (MAX_BATCH_ROWS integer)];
```

#### 用于远程推理的 CREATE MODEL 参数
<a name="r_remote-create-model-parameters"></a>

 *model\$1name*   
模型的名称。schema 中的模型名称必须是唯一的。

FUNCTION *fn\$1name* ( [*data\$1type*] [, ...] )  
函数的名称和输入参数的数据类型。有关所有支持的数据类型，请参阅[数据类型](https://docs.aws.amazon.com/redshift/latest/dg/c_Supported_data_types.html)。`Geography`、`geometry` 和 `hllsketch` 不受支持。  
您还可以在架构中，使用两部分表示法提供函数名称，例如 `myschema.myfunction`。

RETURNS *data\$1type*  
函数返回的值的数据类型。有关所有支持的数据类型，请参阅[数据类型](https://docs.aws.amazon.com/redshift/latest/dg/c_Supported_data_types.html)。`Geography`、`geometry` 和 `hllsketch` 不受支持。

SAGEMAKER *'endpoint\$1name'*[:*'model\$1name'*]   
Amazon SageMaker AI 端点的名称。如果端点名称指向多模型端点，请添加要使用的模型名称。端点必须与 Amazon Redshift 集群托管于同一 AWS 区域和 AWS 账户中。要查找端点，请启动 Amazon SageMaker AI。在**推理**下拉菜单中，选择**端点**。

IAM\$1ROLE \$1 default \$1 'arn:aws:iam::<account-id>:role/<role-name>'\$1  
 使用默认关键字让 Amazon Redshift 使用 IAM 角色，该角色设置为默认值并在 CREATE MODEL 命令运行时与集群关联。或者，您可以指定 IAM 角色的 ARN 来使用该角色。

MAX\$1BATCH\$1ROWS *整数*  
Amazon Redshift 在单个批处理请求中为单个 SageMaker AI 调用发送的最大行数。只有具有远程推理功能的 BYOM 才支持此项。单个批处理中的实际行数还取决于输入大小，但实际行数小于或等于此值。此参数的最小值为 1。最大值为 `INT_MAX`，即 2147483647。仅当输入和返回的数据类型均为 `SUPER` 时，才需要此参数。默认值为 `INT_MAX`，即 2147483647。

当模型部署到 SageMaker AI 端点时，SageMaker AI 会在 Amazon Redshift 中创建模型的信息。然后它通过外部函数执行推理。您可以使用 SHOW MODEL 命令查看 Amazon Redshift 集群上的模型信息。

#### 用于远程推理的 CREATE MODEL 使用说明
<a name="r_remote-create-model-usage-notes"></a>

在使用 CREATE MODEL 进行远程推理之前，请考虑以下事项：
+ 端点必须由拥有 Amazon Redshift 集群的相同AWS账户中托管。
+ 确保 Amazon SageMaker AI 端点有足够的资源来容纳来自 Amazon Redshift 的推理调用，或者可以自动扩展 Amazon SageMaker AI 端点。
+ 如果您不使用 `SUPER` 数据类型作为输入，则模型仅接受逗号分隔值（CSV）格式的输入，该格式对应于 SageMaker AI 中的 `text/CSV` 内容类型。
+ 如果您不使用 `SUPER` 数据类型作为输入，则模型的输出为单个值，其类型是在创建函数时指定的类型。输出格式为逗号分隔值（CSV），通过 SageMaker AI 中的 `text/CSV` 内容类型实现。`VARCHAR` 数据类型不能包含在引号中，也不能包含换行，并且每个输出都必须位于新行中。
+ 模型接受 null 值作为空字符串。
+ 当输入数据类型为 `SUPER` 时，仅支持一个输入参数。
+ 当输入数据类型为 `SUPER` 时，返回的数据类型也必须是 `SUPER`。
+ 当输入和返回的数据类型均为 SUPER 时，需要使用 MAX\$1BATCH\$1ROWS。
+ 当输入数据类型为 `SUPER` 时，端点调用的内容类型为 `application/json`（MAX\$1BATCH\$1ROWS 为 `1` 时）或 `application/jsonlines`（所有其他情况）。
+ 当返回数据类型为 `SUPER` 时，端点调用接受的类型为 `application/json`（MAX\$1BATCH\$1ROWS 为 `1` 时）或 `application/jsonlines`（所有其他情况）。

##### 用于远程推理的 CREATE MODEL 语法示例
<a name="r_remote-create-model-example"></a>

以下示例创建一个使用 SageMaker AI 端点进行预测的模型。确保端点正在运行以进行预测，并在 CREATE MODEL 命令中指定其名称。

```
CREATE MODEL remote_customer_churn
FUNCTION remote_fn_customer_churn_predict (varchar, int, float, float)
RETURNS int
SAGEMAKER 'customer-churn-endpoint'
IAM_ROLE default;
```

 以下示例使用大型语言模型（LLM）创建具备远程推理的 BYOM。托管在 Amazon SageMaker AI Jumpstart 上的 LLM 接受并返回 `application/json` 内容类型，并支持每次调用一个 JSON。输入和返回的数据类型必须为 `SUPER`，且 MAX\$1BATCH\$1ROWS 必须设置为 1。

```
CREATE MODEL sample_super_data_model
FUNCTION sample_super_data_model_predict(super)
RETURNS super
SAGEMAKER 'sample_super_data_model_endpoint'
IAM_ROLE default
SETTINGS (MAX_BATCH_ROWS 1);
```

## 带有 K-MANES 的 CREATE MODEL
<a name="r_k-means_create_model"></a>

Amazon Redshift 支持 K-Means 算法，该算法可对未标记的数据进行分组。此算法可解决需要在数据中发现分组的集群问题。根据未分类数据的相似与不同之处进行分组和分区。

### 带有 K-MANS 语法的 CREATE MODEL
<a name="r_k-means-create-model-synposis"></a>

```
CREATE MODEL model_name
FROM { table_name | ( select_statement ) }
FUNCTION function_name
IAM_ROLE { default | 'arn:aws:iam::<account-id>:role/<role-name>' }
AUTO OFF
MODEL_TYPE KMEANS
PREPROCESSORS 'string'
HYPERPARAMETERS DEFAULT EXCEPT ( K 'val' [, ...] )
SETTINGS (
  S3_BUCKET 'amzn-s3-demo-bucket',
  KMS_KEY_ID 'kms_string', |
    -- optional
  S3_GARBAGE_COLLECT on / off, |
    -- optional
  MAX_CELLS integer, |
    -- optional
  MAX_RUNTIME integer
    -- optional);
```

### 带有 K-MANES 参数的 CREATE MODEL
<a name="r_k-means-create-model-parameters"></a>

 *AUTO OFF*   
关闭预处理器、算法和超参数选择的 CREATE MODEL 自动发现。

MODEL\$1TYPE KMEANS  
指定使用 KMEANS 来训练模型。

PREPROCESSORS 'string'  
将预处理器的某些组合指定为某些列的集合。格式是 columnSet 的列表，以及要应用于每组列的适当转换。Amazon Redshift 支持 3 个 K-Means 预处理器，即 StandardScaler、MinMax 和 NumericPassthrough。如果您不想对 K-Means 应用任何预处理，请明确选择 NumericPassthrough 作为转换器。有关支持的转换器的更多信息，请参阅[使用用户指导参数创建模型](#r_user_guidance-create-model-parameters)。  
K-Means 算法使用欧氏距离来计算相似度。对数据进行预处理可确保模型的功能保持在同等级别并生成可靠的结果。

HYPERPARAMETERS DEFAULT EXCEPT ( K 'val' [, ...] )  
指定是否使用 K-Means 参数。使用 K-Means 算法，必须指定 `K` 参数。有关更多信息，请参阅《Amazon SageMaker AI 开发人员指南》**中的 [K-Means Hyperparameters](https://docs.aws.amazon.com/sagemaker/latest/dg/k-means-api-config.html)。

以下示例为 K-Means 准备数据。

```
CREATE MODEL customers_clusters
FROM customers
FUNCTION customers_cluster
IAM_ROLE default
AUTO OFF
MODEL_TYPE KMEANS
PREPROCESSORS '[
{
  "ColumnSet": [ "*" ],
  "Transformers": [ "NumericPassthrough" ]
}
]'
HYPERPARAMETERS DEFAULT EXCEPT ( K '5' )
SETTINGS (S3_BUCKET 'amzn-s3-demo-bucket');

select customer_id, customers_cluster(...) from customers;
customer_id | customers_cluster
--------------------
12345            1
12346            2
12347            4
12348
```

## CREATE MODEL with Forecast
<a name="r_forecast_model"></a>

Redshift ML 中的预测模型使用 Amazon Forecast 来创建准确的时间序列预测。这样做可以让您使用一段时间内的历史数据来就未来的事件进行预测。Amazon Forecast 的常见使用案例包括：使用零售产品数据来决定如何为库存定价，使用制造数量数据来预测一件商品的订购量，以及使用 Web 流量数据来预测 Web 服务器可能收到多少流量。

 [Amazon Forecast 中的配额限制](https://docs.aws.amazon.com/forecast/latest/dg/limits.html)在 Amazon Redshift 预测模型中执行。例如，最大预测数为 100，但该数量是可调整的。删除预测模型不会自动删除 Amazon Forecast 中的关联资源。如果您删除 Redshift 集群，则所有关联模型也会一并删除。

请注意，预测模型目前仅在以下区域中可用：
+ 美国东部（俄亥俄州）(us-east-2)
+ 美国东部（弗吉尼亚北部）(us-east-1)
+ 美国西部（俄勒冈州）(us-west-2)
+ 亚太地区（孟买）(ap-south-1)
+ 亚太地区（首尔）(ap-northeast-2)
+ 亚太地区（新加坡）(ap-southeast-1)
+ 亚太地区（悉尼）(ap-southeast-2)
+ 亚太地区（东京）(ap-northeast-1)
+ 欧洲地区（法兰克福）(eu-central-1)
+ 欧洲地区（爱尔兰）(eu-west-1)

### CREATE MODEL with Forecast 语法
<a name="r_forecast_model-synopsis"></a>

```
CREATE [ OR REPLACE ] MODEL forecast_model_name 
FROM { table_name | ( select_query ) } 
TARGET column_name
IAM_ROLE { default | 'arn:aws:iam::<account-id>:role/<role-name>'} 
AUTO ON
MODEL_TYPE FORECAST
SETTINGS (
  S3_BUCKET 'amzn-s3-demo-bucket',
  HORIZON integer,
  FREQUENCY forecast_frequency
  [PERCENTILES '0.1', '0.5', '0.9']
  )
```

### CREATE MODEL with Forecast 参数
<a name="r_forecast_model-parameters"></a>

 *forecast\$1model\$1name*   
模型的名称。模型名称必须唯一。

FROM \$1 table\$1name \$1 ( select\$1query ) \$1  
指定训练数据的 table\$1name 或查询。这既可以是系统中的现有表，也可以是用括号括起来的兼容 Amazon RedShift 的 SELECT 查询。表或查询结果必须至少包含三列：(1) 一个指定时间序列名称的 varchar 列。每个数据集可以有多个时间序列；(2) 一个日期时间列；以及 (3) 要预测的目标列。此目标列必须为整数或浮点类型。如果您提供的数据集包含三列以上，Amazon Redshift 会假定所有其他列都是相关时间序列的一部分。请注意，相关时间序列必须为整数或浮点类型。有关相关时间序列的更多信息，请参阅[使用相关时间序列数据集](https://docs.aws.amazon.com/forecast/latest/dg/related-time-series-datasets.html)。

TARGET column\$1name  
成为预测目标的列的名称。FROM 子句中必须存在该列。

IAM\$1ROLE \$1 default \$1 'arn:aws:iam::<account-id>:role/<role-name>' \$1  
使用默认关键字让 Amazon Redshift 使用设置为默认值并在 CREAT MODEL 命令运行时与集群关联的 IAM 角色。或者，您可以指定 IAM 角色的 ARN 来使用该角色。

AUTO ON  
打开算法和超参数选择的 CREATE MODEL 自动发现。在创建预测模型时指定 On 表示使用 Forecast AutoPredictor，其中 Amazon Forecast 会将算法的最佳组合应用于数据集中的每个时间序列。

MODEL\$1TYPE FORECAST  
指定使用 FORECAST 来训练模型。

S3\$1BUCKET 'amzn-s3-demo-bucket'  
您之前创建的 Amazon Simple Storage Service 桶的名称，该桶用于在 Amazon Redshift 和 Amazon Forecast 之间共享训练数据和构件。在卸载训练数据之前，Amazon Redshift 会在此桶中创建一个子文件夹。训练完成后，Amazon Redshift 会删除创建的子文件夹及其内容。

HORIZON 整数  
预测模型可以返回的最大预测数。模型一旦经过训练，您就无法更改此整数。

FREQUENCY forecast\$1frequency  
指定您希望的预测时间粒度。可用的选项为 `Y | M | W | D | H | 30min | 15min | 10min | 5min | 1min`。如果要训练预测模型，则为必填项。

PERCENTILES 字符串  
一个以逗号分隔的字符串，指定用于训练预测器的预测类型。预测类型可以是从 0.01 到 0.99 的分位数，增量为 0.01 或更高。您也可以使用均值指定均值预测。您最多可以指定五种预测类型。

以下示例演示了如何创建简单的预测模型。

```
CREATE MODEL forecast_example
FROM forecast_electricity_
TARGET target 
IAM_ROLE 'arn:aws:iam::<account-id>:role/<role-name>'
AUTO ON 
MODEL_TYPE FORECAST
SETTINGS (S3_BUCKET 'amzn-s3-demo-bucket',
          HORIZON 24,
          FREQUENCY 'H',
          PERCENTILES '0.25,0.50,0.75,mean',
          S3_GARBAGE_COLLECT OFF);
```

创建预测模型后，您可以使用预测数据创建新表。

```
CREATE TABLE forecast_model_results as SELECT Forecast(forecast_example)
```

然后，您可以查询新表以获得预测。

```
SELECT * FROM forecast_model_results
```

# CREATE PROCEDURE
<a name="r_CREATE_PROCEDURE"></a>

创建新的存储过程或者替换当前数据库的现有过程。

有关更多信息以及示例，请参阅 [在 Amazon Redshift 中创建存储过程](stored-procedure-overview.md)。

## 所需的权限
<a name="r_CREATE_PROCEDURE-privileges"></a>

您必须通过以下方式之一获得权限，才能运行 CREATE OR REPLACE PROCEDURE：
+ CREATE PROCEDURE：
  + Superuser
  + 对创建存储过程的架构具有 CREATE 和 USAGE 权限的用户
+ REPLACE PROCEDURE：
  + Superuser
  + 程序拥有者

## 语法
<a name="r_CREATE_PROCEDURE-synopsis"></a>

```
CREATE [ OR REPLACE ] PROCEDURE sp_procedure_name  
  ( [ [ argname ] [ argmode ] argtype [, ...] ] )
[ NONATOMIC ]
AS $$
  procedure_body
$$ LANGUAGE plpgsql
[ { SECURITY INVOKER | SECURITY DEFINER } ]
[ SET configuration_parameter { TO value | = value } ]
```

## 参数
<a name="r_CREATE_PROCEDURE-parameters"></a>

 OR REPLACE   
一个子句，指定如果某个过程与已存在的此过程具有相同的名称和输入参数数据类型或签名，则替换现有的过程。您只能将某个过程替换为定义一组相同数据类型的新过程。  
如果您定义的过程与现有过程具有相同的名称，但签名不同，则您将创建新的过程。换句话说，过程名称已重载。有关更多信息，请参阅 [重载过程名称](stored-procedure-naming.md#stored-procedure-overloading-name)。

 *sp\$1procedure\$1name*   
过程的名称。如果您指定 schema 名称（例如 **myschema.myprocedure**），则在指定的 schema 中创建该过程。否则，将在当前 schema 中创建过程。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。  
我们建议您将所有的存储过程名称添加前缀 `sp_`。Amazon Redshift 保留 `sp_` 前缀，用于存储过程名称。通过使用前缀 `sp_`，可以确保存储过程名称不会与任何现有或将来的 Amazon Redshift 内置存储过程或函数名称冲突。有关更多信息，请参阅 [命名存储过程](stored-procedure-naming.md)。  
如果输入参数的数据类型或签名不同，您可以定义多个具有相同名称的过程。换句话说，在这种情况下过程名称会重载。有关更多信息，请参阅[重载过程名称](stored-procedure-naming.md#stored-procedure-overloading-name)

*[argname] [ argmode] argtype*   
参数名称、参数模式和数据类型的列表。仅需要数据类型。名称和模式是可选的，可以切换它们的位置。  
参数模式可以是 IN、OUT 或 INOUT。默认值为 IN。  
您可以使用 OUT 和 INOUT 参数从过程调用中返回一个或多个值。当存在 OUT 或 INOUT 参数时，过程调用返回一个包含 *n* 列的结果行，其中 *n* 是 OUT 或 INOUT 参数的总数。  
INOUT 参数同时是输入和输出参数。*输入参数* 包括 IN 和 INOUT 参数，而*输出参数* 包括 OUT 和 INOUT 参数。  
OUT 参数未指定为 CALL 语句的一部分。在存储过程 CALL 语句中指定 INOUT 参数。当从嵌套调用传递和返回值时，以及返回 `refcursor` 时，INOUT 参数很有用。有关 `refcursor` 类型的更多信息，请参阅 [游标](c_PLpgSQL-statements.md#r_PLpgSQL-cursors)。  
参数数据类型可以是任何标准的 Amazon Redshift 数据类型。另外，参数数据类型可以是 `refcursor`。  
您最多可以指定 32 个输入参数和 32 个输出参数。

AS \$1\$1 *procedure\$1body* \$1\$1   
包含要执行的过程的构造。需要文字关键字 AS \$1\$1 和 \$1\$1。  
Amazon Redshift 要求您使用称为“美元引号”的格式，在您的过程中包含语句。包含的任何内容将按原样传递。您不必对任何特殊字符进行转义，因为字符串的内容是按照其字面涵义编写的。  
通过*美元引号* 格式，您可以使用一对美元符号 (\$1\$1) 来指示要运行的语句的开头和结尾，如以下示例所示。  

```
$$ my statement $$
```
（可选）在每对美元符号之间，可以指定字符串来帮助识别语句。您使用的字符串必须在括起字符对的开始和结束都是相同的。该字符串区分大小写，它遵循与不带括起字符的标识符相同的约束，但有一点除外，它不能包含美元符号。以下示例使用字符串 test。  

```
$test$ my statement $test$
```
此语法对嵌套的美元引号也很有用。有关“美元引号”格式的更多信息，请参阅 PostgreSQL 文档的[词法结构](https://www.postgresql.org/docs/9.0/sql-syntax-lexical.html)中的“使用美元符号括起的常量字符串”。

 *procedure\$1body*   
一组有效的 PL/pgSQL 语句。PL/pgSQL 语句使用程序性结构（包括循环和条件表达式）增强 SQL 命令，以控制逻辑流。可以在过程主体中使用大部分 SQL 命令，包括数据修改语言 (DML)（例如 COPY、UNLOAD 和 INSERT）以及数据定义语言 (DDL)（例如 CREATE TABLE）。有关更多信息，请参阅 [PL/pgSQL 语言参考](c_pl_pgSQL_reference.md)。

LANGUAGE *plpgsql*  
语言值。指定 `plpgsql`。您必须具有使用 `plpgsql` 语言的权限。有关更多信息，请参阅 [GRANT](r_GRANT.md)。

NONATOMIC  
在非原子事务模式下创建存储过程。NONATOMIC 模式会自动提交过程内部的语句。此外，当 NONATOMIC 过程内部出现错误时，如果错误由异常块处理，则不会重新引发错误。有关更多信息，请参阅[管理事务](stored-procedure-transaction-management.md)和[RAISE](c_PLpgSQL-statements.md#r_PLpgSQL-messages-errors)。  
当您将存储过程定义为 `NONATOMIC` 时，请考虑以下各项：  
+ 当您进行嵌套的存储过程调用时，所有过程都必须在相同的事务模式下创建。
+ 在 NONATOMIC 模式下创建过程时，不支持 `SECURITY DEFINER` 选项和 `SET configuration_parameter` 选项。
+ 任何打开的游标（显式或隐式）在处理隐式提交时会自动关闭。因此，您必须在开始游标循环之前打开显式事务，以确保不会隐式提交循环迭代中的任何 SQL。

SECURITY INVOKER \$1 SECURITY DEFINER  
指定 `NONATOMIC` 时不支持 `SECURITY DEFINER` 选项。  
该过程的安全模式确定过程在运行时的访问权限。该过程必须具有访问基础数据库对象的权限。  
对于 SECURITY INVOKER 模式，该过程使用调用该过程的用户的权限。用户必须对基础数据库对象具有显式权限。默认值为 SECURITY INVOKER。  
对于 SECURITY DEFINER 模式，此过程使用过程拥有者的权限。过程拥有者定义为在运行时拥有此过程的用户，而不一定是最初定义此过程的用户。调用该过程的用户需要具有该过程的执行权限，但不需要对基础对象具有任何权限。

SET configuration\$1parameter \$1 TO value \$1 = value \$1  
指定 `NONATOMIC` 时不支持这些选项。  
输入过程时，SET 子句会将指定的 `configuration_parameter` 设置为指定的值。然后，当该过程退出时，该子句会将 `configuration_parameter` 还原为其早期值。

## 使用说明
<a name="r_CREATE_PROCEDURE-usage"></a>

如果存储过程是使用 SECURITY DEFINER 选项创建的，则在存储过程中调用 CURRENT\$1USER 函数时，Amazon Redshift 会返回存储过程拥有者的用户名。

## 示例
<a name="r_CREATE_PROCEDURE-examples"></a>

**注意**  
如果在运行这些示例时，您遇到了类似于下文的错误：  

```
ERROR: 42601: [Amazon](500310) unterminated dollar-quoted string at or near "$$
```
请参阅 [Amazon Redshift 中的存储过程概览](stored-procedure-create.md)。

以下示例创建带有两个输入参数的过程。

```
CREATE OR REPLACE PROCEDURE test_sp1(f1 int, f2 varchar(20))
AS $$
DECLARE
  min_val int;
BEGIN
  DROP TABLE IF EXISTS tmp_tbl;
  CREATE TEMP TABLE tmp_tbl(id int);
  INSERT INTO tmp_tbl values (f1),(10001),(10002);
  SELECT min_val MIN(id) FROM tmp_tbl;
  RAISE INFO 'min_val = %, f2 = %', min_val, f2;
END;
$$ LANGUAGE plpgsql;
```

**注意**  
 在编写存储过程时，我们建议使用最佳实践来保护敏感值：  
 不要在存储过程逻辑中对任何敏感信息进行硬编码。例如，不要在存储过程主体的 CREATE USER 语句中分配用户密码。这会带来安全风险，因为硬编码值可以作为架构元数据记录在目录表中。而是应通过参数将诸如密码之类的敏感值作为参量传递给存储过程。  
有关存储过程的更多信息，请参阅 [CREATE PROCEDURE](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_PROCEDURE.html) 和[在 Amazon Redshift 中创建存储过程](https://docs.aws.amazon.com/redshift/latest/dg/stored-procedure-overview.html)。有关目录表的更多信息，请参阅[系统目录表](https://docs.aws.amazon.com/redshift/latest/dg/c_intro_catalog_views.html)。

以下示例使用一个 IN 参数、一个 OUT 参数和一个 INOUT 参数创建一个过程。

```
CREATE OR REPLACE PROCEDURE test_sp2(f1 IN int, f2 INOUT varchar(256), out_var OUT varchar(256))
AS $$
DECLARE
  loop_var int;
BEGIN
  IF f1 is null OR f2 is null THEN
    RAISE EXCEPTION 'input cannot be null';
  END IF;
  DROP TABLE if exists my_etl;
  CREATE TEMP TABLE my_etl(a int, b varchar);
    FOR loop_var IN 1..f1 LOOP
        insert into my_etl values (loop_var, f2);
        f2 := f2 || '+' || f2;
    END LOOP;
  SELECT INTO out_var count(*) from my_etl;
END;
$$ LANGUAGE plpgsql;
```

以下示例创建一个使用 `SECURITY DEFINER` 参数的过程。使用拥有该过程的用户的权限来运行此过程。

```
CREATE OR REPLACE PROCEDURE sp_get_current_user_definer()
AS $$
DECLARE curr_user varchar(250);
BEGIN
  SELECT current_user INTO curr_user;
  RAISE INFO '%', curr_user;
END;
$$ LANGUAGE plpgsql
SECURITY DEFINER;
```

以下示例创建一个使用 `SECURITY INVOKER` 参数的过程。使用运行该过程的用户的权限来运行此过程。

```
CREATE OR REPLACE PROCEDURE sp_get_current_user_invoker()
AS $$
DECLARE curr_user varchar(250);
BEGIN
  SELECT current_user INTO curr_user;
  RAISE INFO '%', curr_user;
END;
$$ LANGUAGE plpgsql
SECURITY INVOKER;
```

# CREATE RLS POLICY
<a name="r_CREATE_RLS_POLICY"></a>

创建新的行级安全策略以提供对数据库对象的精细访问。

超级用户和具有 sys:secadmin 角色的用户或角色可以创建策略。

## 语法
<a name="r_CREATE_RLS_POLICY-synopsis"></a>

```
CREATE RLS POLICY { policy_name | database_name.policy_name }
[ WITH (column_name data_type [, ...]) [ [AS] relation_alias ] ]
USING ( using_predicate_exp )
```

## 参数
<a name="r_CREATE_RLS_POLICY-parameters"></a>

 *policy\$1name*   
策略的名称。

database\$1name  
将在其中创建策略的数据库的名称。可以在连接的数据库或支持 Amazon Redshift 联合身份验证权限的数据库上创建策略。

WITH (*column\$1name data\$1type [, ...]*)   
指定 *column\$1name* 和 *data\$1type* 引用策略附加到的表的列。  
仅当 RLS 策略没有引用策略附加到的表的任何列时，您才可以省略 WITH 子句。

AS *relation\$1alias*  
为 RLS 策略将附加到的表指定可选别名。

USING (* using\$1predicate\$1exp *)  
指定应用于查询的 WHERE 子句的筛选器。Amazon Redshift 会在查询级别的用户谓词之前应用策略谓词。例如，**current\$1user = ‘joe’ and price > 10** 限制 Joe 只能查看价格高于 10 美元的记录。

有关在 Amazon Redshift 联合身份验证权限目录上使用 CREATE RLS POLICY 的信息，请参阅[使用 Amazon Redshift 联合身份验证权限管理访问控制](https://docs.aws.amazon.com/redshift/latest/dg/federated-permissions-managing-access.html)。

## 使用说明
<a name="r_CREATE_RLS_POLICY-usage"></a>

在使用 CREATE RLS POLICY 语句时，请遵守以下规则：
+ Amazon Redshift 支持可以作为查询的 WHERE 子句的组成部分的筛选器。
+ 所有附加到表的策略都必须使用相同的表别名创建。
+ 您必须使用 GRANT 和 REVOKE 语句来显式授予和撤消对引用查找表的 RLS 策略的 SELECT 权限。查找表是在策略定义中使用的表对象。有关更多信息，请参阅[GRANT](r_GRANT.md)和[REVOKE](r_REVOKE.md)。
+ Amazon Redshift 行级安全性不支持策略定义中的以下对象类型：目录表、跨数据库关系、外部表、常规视图、后期绑定视图、已开启 RLS 策略的表以及临时表。

## 示例
<a name="r_CREATE_RLS_POLICY-examples"></a>

以下示例创建一个名为 policy\$1concerts 的 RLS 策略。此策略应用于名为 catgroup 的 VARCHAR(10) 列，并将 USING 筛选条件设置为仅返回 catgroup 值为 `'Concerts'` 的行。

```
CREATE RLS POLICY policy_concerts
WITH (catgroup VARCHAR(10))
USING (catgroup = 'Concerts');
```

有关使用 RLS 策略的端到端示例，请参阅[行级安全性端到端示例](t_rls-example.md)。

# CREATE ROLE
<a name="r_CREATE_ROLE"></a>

创建一个新的自定义角色，该角色是权限的集合。有关 Amazon Redshift 系统定义的角色列表，请参阅[Amazon Redshift 系统定义的角色](r_roles-default.md)。查询 [SVV\$1ROLES](r_SVV_ROLES.md) 以查看集群或工作组中当前创建的角色。

可以创建的角色数量有配额。有关更多信息，请参阅《Amazon Redshift 管理指南》**中的 [Amazon Redshift 中的配额和限制](https://docs.aws.amazon.com/redshift/latest/mgmt/amazon-redshift-limits.html)。

## 所需的权限
<a name="r_CREATE_ROLE-privileges"></a>

以下是 CREATE ROLE 所需的权限：
+ Superuser
+ 具有 CREATE ROLE 权限的用户

## 语法
<a name="r_CREATE_ROLE-synopsis"></a>

```
CREATE ROLE role_name
[ EXTERNALID external_id ]
```

## 参数
<a name="r_CREATE_ROLE-parameters"></a>

*role\$1name*  
角色的名称。角色名称必须唯一且不能与任何用户名相同。角色名称不能为保留字。  
超级用户或具有 CREATE ROLE 权限的普通用户可以创建角色。如果用户不是超级用户，但已被授予该角色的 USAGE 权限及 WITH GRANT OPTION 选项以及 ALTER 权限，则可以将此角色授予任何人。

EXTERNALID *external\$1id*  
角色的标识符，与身份提供者关联。有关更多信息，请参阅 [Amazon Redshift 的原生身份提供者 (IdP) 联合身份验证](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-native-idp.html)。

## 示例
<a name="r_CREATE_ROLE-examples"></a>

下面的示例将创建角色 `sample_role1`。

```
CREATE ROLE sample_role1;
```

以下示例创建角色 `sample_role1`，其中包含与身份提供者关联的外部 ID。

```
CREATE ROLE sample_role1 EXTERNALID "ABC123";
```

# CREATE SCHEMA
<a name="r_CREATE_SCHEMA"></a>

定义当前数据库的新 schema。

## 所需的权限
<a name="r_CREATE_SCHEMA-privileges"></a>

以下是 CREATE SCHEMA 所需的权限：
+ Superuser
+ 具有 CREATE SCHEMA 权限的用户

## 语法
<a name="r_CREATE_SCHEMA-synopsis"></a>

```
CREATE SCHEMA [ IF NOT EXISTS ] schema_name [ AUTHORIZATION username ]
           [ QUOTA {quota [MB | GB | TB] | UNLIMITED} ] [ schema_element [ ... ]

CREATE SCHEMA AUTHORIZATION username[ QUOTA {quota [MB | GB | TB] | UNLIMITED} ] [ schema_element [ ... ] ]
```

## 参数
<a name="r_CREATE_SCHEMA-parameters"></a>

 IF NOT EXISTS   
这个子句指示，如果指定的 schema 已存在，则命令不应进行任何更改，并返回一条指示 schema 存在的消息，而不是以错误终止。  
此子句在编写脚本时很有用，可使脚本在 CREATE SCHEMA 尝试创建已存在的 schema 时不会失败。

 *schema\$1name*   
新 schema 的名称。schema 名称不能为 `PUBLIC`。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。  
[search\$1path](r_search_path.md) 配置参数中的 schema 列表确定了在不使用 schema 名称的情况下引用同名对象的优先顺序。

AUTHORIZATION   
一个向指定的用户提供所有权的子句。

 *username*   
schema 所有者的名称。

 *schema\$1element*   
要在 schema 中创建的一个或多个对象的定义。

QUOTA  
指定的 schema 可以使用的最大磁盘空间量。此空间是整体磁盘使用情况。它包括所有永久表、指定 schema 下的实体化视图以及在每个计算节点上具有 ALL 分布的所有表的重复副本。schema 配额不考虑作为临时命名空间或 schema 的一部分创建的临时表。  
要查看已配置的 schema 配额，请参阅[SVV\$1SCHEMA\$1QUOTA\$1STATE](r_SVV_SCHEMA_QUOTA_STATE.md)。  
要查看已超出 schema 配额的记录，请参阅[STL\$1SCHEMA\$1QUOTA\$1VIOLATIONS](r_STL_SCHEMA_QUOTA_VIOLATIONS.md)。  
Amazon Redshift 将选定值转换为 MB。如果您未指定值，则 GB 是默认的测量单位。  
您必须是数据库超级用户才能设置和更改 schema 配额。不具有超级用户身份但具有 CREATE SCHEMA 权限的用户可以创建具有定义的配额的 schema。如果创建一个 schema 而不定义配额，则该 schema 具有无限的配额。如果将配额设置为低于 schema 所使用的当前值，则在您释放磁盘空间之前，Amazon Redshift 将不允许进一步摄入。DELETE 语句从表中删除数据，并且仅当 VACUUM 运行时才释放磁盘空间。  
Amazon Redshift 会在提交事务之前检查每个事务是否存在违反配额的情况。Amazon Redshift 会根据设置的配额检查每个修改后的 schema 的大小（schema 中所有表使用的磁盘空间）。由于配额冲突检查是在事务结束时进行的，因此，大小限制可能会在事务被提交之前暂时超过事务配额。当事务超出配额时，Amazon Redshift 会停止事务，禁止后续提取，并恢复所有更改，直到您释放磁盘空间。由于后台 VACUUM 和内部清理，在取消事务后检查架构时，架构可能不完整。  
作为例外，Amazon Redshift 会忽略配额违规并在某些情况下提交事务。Amazon Redshift 会针对仅由以下一个或多个语句组成的事务执行此操作，而在同一事务中没有 INSERT 或 COPY 摄入语句：  
+ DELETE
+ TRUNCATE
+ VACUUM
+ DROP TABLE
+ ALTER TABLE APPEND 仅在将数据从完整 schema 移至非完整 schema 时使用

 *UNLIMITED*   
Amazon Redshift 不对 schema 的总大小的增长施加任何限制。

## 限制
<a name="r_CREATE_SCHEMA-limit"></a>

Amazon Redshift 针对 schema 强制实施以下限制。
+ 每个数据库最多有 9900 个 schemas。

## 示例
<a name="r_CREATE_SCHEMA-examples"></a>

以下示例创建一个名为 US\$1SALES 的 schema 并向用户 DWUSER 授予所有权。

```
create schema us_sales authorization dwuser;
```

以下示例创建一个名为 US\$1SALES 的 schema，向用户 DWUSER 授予所有权，并将配额设置为 50 GB。

```
create schema us_sales authorization dwuser QUOTA 50 GB;
```

要查看新 schema，请查询 PG\$1NAMESPACE 目录表，如下所示。

```
select nspname as schema, usename as owner
from pg_namespace, pg_user
where pg_namespace.nspowner = pg_user.usesysid
and pg_user.usename ='dwuser';

   schema |  owner
----------+----------
 us_sales | dwuser
(1 row)
```

以下示例创建 US\$1SALES schema，如果 schema 已存在，将不执行任何操作并返回一条消息。

```
create schema if not exists us_sales;
```

# CREATE TABLE
<a name="r_CREATE_TABLE_NEW"></a>

在当前数据库中创建一个新表。您可以定义一个列的列表，用于存储不同类型的数据。此表的所有者为 CREATE TABLE 命令的发布者。

## 所需的权限
<a name="r_CREATE_TABLE-privileges"></a>

以下是 CREATE TABLE 所需的权限：
+ Superuser
+ 具有 CREATE TABLE 权限的用户

## 语法
<a name="r_CREATE_TABLE_NEW-synopsis"></a>

```
CREATE [ [LOCAL ] { TEMPORARY | TEMP } ] TABLE
[ IF NOT EXISTS ] table_name
( { column_name data_type [column_attributes] [ column_constraints ]
  | table_constraints
  | LIKE parent_table [ { INCLUDING | EXCLUDING } DEFAULTS ] }
  [, ... ]  )
[ BACKUP { YES | NO } ]
[table_attributes]

where column_attributes are:
  [ DEFAULT default_expr ]
  [ IDENTITY ( seed, step ) ]
  [ GENERATED BY DEFAULT AS IDENTITY ( seed, step ) ]
  [ ENCODE encoding ]
  [ DISTKEY ]
  [ SORTKEY ]
  [ COLLATE { CASE_SENSITIVE | CS | CASE_INSENSITIVE | CI } ]

and column_constraints are:
  [ { NOT NULL | NULL } ]
  [ { UNIQUE  |  PRIMARY KEY } ]
  [ REFERENCES reftable [ ( refcolumn ) ] ]

and table_constraints  are:
  [ UNIQUE ( column_name [, ... ] ) ]
  [ PRIMARY KEY ( column_name [, ... ] )  ]
  [ FOREIGN KEY (column_name [, ... ] ) REFERENCES reftable [ ( refcolumn ) ]


and table_attributes are:
  [ DISTSTYLE { AUTO | EVEN | KEY | ALL } ]
  [ DISTKEY ( column_name ) ]
  [ [COMPOUND | INTERLEAVED ] SORTKEY ( column_name [,...]) |  [ SORTKEY AUTO ] ]
  [ ENCODE AUTO ]
```

## 参数
<a name="r_CREATE_TABLE_NEW-parameters"></a>

LOCAL   
可选。虽然语句中接受此关键词，但它在 Amazon Redshift 中没有任何作用。

TEMPORARY \$1 TEMP   
一个关键字，可创建仅在当前会话中可见的临时表。在从中创建表的会话结束时，将自动删除此表。临时表可具有与永久表相同的名称。在特定于会话的单独 schema 中创建临时表。(您无法为此 schema 指定名称。) 此临时架构将成为搜索路径中的第一个架构，因此临时表优先于永久表，除非您使用架构名称来限定表名以访问永久表。有关 schema 和优先顺序的更多信息，请参阅 [search\$1path](r_search_path.md)。  
默认情况下，数据库用户有权通过其在 PUBLIC 组中自动获得的成员资格来创建临时表。要拒绝向用户授予此权限，可从 PUBLIC 组撤消 TEMP 权限，然后仅将 TEMP 权限显式授予特定用户或用户组。

IF NOT EXISTS  
这个子句指示，如果指定的表已存在，命令应不进行任何更改并返回一条指示表存在的消息，而不是出错停止。请注意，现有表可能与已创建的表完全不同；仅比较表名。  
此子句在编写脚本时很有用，可使脚本在 CREATE TABLE 尝试创建已存在的表时不会失败。

 *table\$1name*   
要创建的表的名称。  
如果指定以“\$1”开始的表名，表会创建为临时表。以下是示例：  

```
create table #newtable (id int);
```
您还可使用“\$1”引用该表。例如：  

```
select * from #newtable;
```
表名称的最大长度为 127 个字节；更长的名称将被截断为 127 个字节。您可以使用 UTF-8 多字节字符，每个字符最多为四个字节。Amazon Redshift 按节点类型对每个集群强制实施表数量的配额，包括用户定义的临时表以及查询处理或系统维护期间由 Amazon Redshift 创建的临时表。也可使用数据库名称和 schema 名称来限定表名称。在下面的示例中，`tickit` 是数据库名称，`public` 是 schema 名称，而 `test` 是表名称。  

```
create table tickit.public.test (c1 int);
```
如果数据库或 schema 不存在，则不会创建表，并且语句将返回错误。您无法在系统数据库 `template0`、`template1`、`padb_harvest` 或 `sys:internal` 中创建表或视图。  
如果提供 schema 名称，则在该 schema 中创建新表（假定创建者有权访问 schema）。表名称必须是该 schema 中的唯一名称。如果未指定 schema，则可使用当前数据库 schema 创建表。如果您创建的是临时表，则无法指定 schema 名称，因为特定 schema 中存在临时表。  
同一个数据库中可同时存在多个同名的临时表，前提是这些临时表是在单独的会话中创建的，因为这些表将分配给不同的 schema。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。

 *column\$1name*   
要在新表中创建的列的名称。列名称的最大长度为 127 个字节；更长的名称将被截断为 127 个字节。您可以使用 UTF-8 多字节字符，每个字符最多为四个字节。可在单个表中定义的列的最大数目为 1,600。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。  
如果您创建的是“宽表”，请注意，在加载和查询处理期间，不要让列列表超出中间结果的行宽度边界。有关更多信息，请参阅 [使用说明](#r_CREATE_TABLE_usage)。

 *data\$1type*   
要创建的列的数据类型。对于 CHAR 和 VARCHAR 列，您可以使用 MAX 关键字而不是声明最大长度。MAX 将最大长度设置为 4096 字节（对于 CHAR）或 65535 字节（对于 VARCHAR）。GEOMETRY 对象的最大大小为 1048447 字节。  
有关 Amazon Redshift 支持的数据类型的信息，请参阅[数据类型](c_Supported_data_types.md)。

DEFAULT *default\$1expr*   <a name="create-table-default"></a>
一个为列分配默认数据值的子句。*default\$1expr* 的数据类型必须匹配列的数据类型。DEFAULT 值必须是无变量的表达式。不允许子查询、对当前表中其他列的交叉引用和用户定义的函数。  
*default\$1expr* 表达式可用于未为列指定值的任何 INSERT 操作。如果未指定默认值，则列的默认值为 null。  
如果具有定义的列列表的 COPY 操作忽略具有 DEFAULT 值的列，则 COPY 命令将插入 *default\$1expr* 的值。

IDENTITY(*seed*, *step*)   <a name="identity-clause"></a>
一个指定列为 IDENTITY 列的子句。IDENTITY 列包含唯一的自动生成的值。IDENTITY 列的数据类型必须为 INT 或 BIGINT。  
使用 `INSERT` 或 `INSERT INTO [tablename] VALUES()` 语句添加行时，这些值以指定为 *seed* 的值开始，并按照指定为 *step* 的数字递增。  
使用 `INSERT INTO [tablename] SELECT * FROM` 或 `COPY` 语句加载表时，数据将并行加载并分发到节点切片。为确保身份值唯一，Amazon Redshift 在创建身份值时跳过多个值。身份值是唯一的，但顺序可能与源文件中的顺序不匹配。

GENERATED BY DEFAULT AS IDENTITY (*seed*, *step*)   <a name="identity-generated-bydefault-clause"></a>
指定该列为默认 IDENTITY 列并使您可以自动为该列分配唯一值的子句。IDENTITY 列的数据类型必须为 INT 或 BIGINT。添加不含值的行时，这些值以指定为 *seed* 的值开始，并按照指定为 *step* 的数字递增。有关如何生成值的信息，请参阅[IDENTITY](#identity-clause)。  
此外，在 INSERT、UPDATE 或 COPY 期间，您可以提供没有 EXPLICIT\$1IDS 的值。Amazon Redshift 会使用该值插入到身份列，而不是使用系统生成的值。该值可以是重复值、小于 seed 的值或介于 step 值之间的值。Amazon Redshift 不检查列中值的唯一性。提供一个值不会影响下一个系统生成的值。  
如果您需要在列中保持唯一性，请勿添加重复值。而是添加小于 seed 或介于 step 值之间的唯一值。
记住与默认身份列有关的以下信息：  
+ 默认身份列为 NOT NULL。不能插入 NULL。
+ 要将生成的值插入默认身份列，请使用关键字 `DEFAULT`。

  ```
  INSERT INTO tablename (identity-column-name) VALUES (DEFAULT);
  ```
+ 覆盖默认身份列的值不会影响下一个生成的值。
+ 您无法使用 ALTER TABLE ADD COLUMN 语句添加默认身份列。
+ 您可以使用 ALTER TABLE APPEND 语句附加默认身份列。

ENCODE *encoding*   
列的压缩编码。ENCODE AUTO 是表的默认设置。Amazon Redshift 会自动管理表中所有列的压缩编码。如果为表中的任何列指定压缩编码，则表不再设置为 ENCODE AUTO。Amazon Redshift 不再自动管理表中所有列的压缩编码。您可以为表指定 ENCODE AUTO 选项，以使 Amazon Redshift 能够自动管理表中所有列的压缩编码。  
  
Amazon Redshift 会自动为您未指定压缩编码的列分配初始压缩编码，如下所示：  
+ 默认情况下，会为临时表中的所有列分配 RAW 压缩。
+ 为定义为排序键的列分配 RAW 压缩。
+ 定义为 BOOLEAN、REAL、DOUBLE PRECISION、GEOMETRY 或 GEOGRAPHY 数据类型的列分配了 RAW 压缩。
+ 定义为 SMALLINT、INTEGER、BIGINT、DECIMAL、DATE、TIME、TIMETZ、TIMESTAMP 或 TIMESTAMPTZ 的列分配了 AZ64 压缩。
+ 定义为 CHAR、VARCHAR 或 VARBYTE 的列分配了 LZO 压缩。
如果您不希望压缩某个列，请显式指定 RAW 编码。
 支持以下[compression encodings](c_Compression_encodings.md#compression-encoding-list)：  
+ AZ64
+ BYTEDICT
+ DELTA
+ DELTA32K
+ LZO
+ MOSTLY8
+ MOSTLY16
+ MOSTLY32
+ RAW（无压缩）
+ RUNLENGTH
+ TEXT255
+ TEXT32K
+ ZSTD

DISTKEY  
一个指定列为表的分配键的关键字。一个表中只能有一个列可成为分配键。可在列名后使用 DISTKEY 关键字，也可使用 DISTKEY (*column\$1name*) 语法将该关键字用作表定义的一部分。每种方法的效果相同。有关更多信息，请参阅本主题后面的 DISTSTYLE 参数。  
分配键列的数据类型可以为：BOOLEAN、REAL、DOUBLE PRECISION、SMALLINT、INTEGER、BIGINT、DECIMAL、DATE、TIME、TIMETZ、TIMESTAMP 或 TIMESTAMPTZ、CHAR 或 VARCHAR。

SORTKEY  
一个指定列为表的排序键的关键字。在数据加载到表中后，将按指定为排序键的一个或多个列对数据进行排序。可在列名后使用 SORTKEY 关键字来指定单列排序键，也可使用 SORTKEY (*column\$1name* [, ...]) 语法将一个或多个列指定为表的排序键列。仅使用此语法创建复合排序键。  
您最多可以为每个表定义 400 个 SORTKEY 列。  
排序键列的数据类型可以为：BOOLEAN、REAL、DOUBLE PRECISION、SMALLINT、INTEGER、BIGINT、DECIMAL、DATE、TIME、TIMETZ、TIMESTAMP 或 TIMESTAMPTZ、CHAR 或 VARCHAR。

COLLATE \$1 CASE\$1SENSITIVE \$1 CS \$1 CASE\$1INSENSITIVE \$1 CI \$1  
指定列中的字符串搜索或比较是区分大小写还是不区分大小写的子句。默认值与数据库的当前区分大小写的配置相同。  
仅基于字符串的数据类型才支持 COLLATE，包括 CHAR、VARCHAR 以及 SUPER 列中的字符串值。有关对 SUPER 数据进行不区分大小写的查询的详细信息，请参阅[不区分大小写的查询](query-super.md#case-insensitive-super-queries)。  
要查找数据库排序规则信息，请使用以下命令：  

```
SELECT db_collation();
                     
db_collation
----------------
 case_sensitive
(1 row)
```
CASE\$1SENSITIVE 和 CS 可以互换，生成的结果相同。同样，CASE\$1INSENSITIVE 和 CI 可以互换，生成的结果相同。

NOT NULL \$1 NULL   
NOT NULL 指定列中不允许包含 null 值。NULL（默认值）指定列接受 null 值。默认情况下，将 IDENTITY 列声明为 NOT NULL。

UNIQUE  
一个指定列只能包含唯一值的关键字。唯一表约束的行为与列约束的行为相同，但前者能够跨多个列。要定义唯一表约束，请使用 UNIQUE ( *column\$1name* [, ... ] ) 语法。  
唯一约束是信息性的，而不由系统强制实施。

PRIMARY KEY  
一个指定列为表的主键的关键字。通过使用列定义，只能将一个列定义为主键。要使用多列主键定义表约束，请使用 PRIMARY KEY ( *column\$1name* [, ... ] ) 语法。  
通过将一个列标识为主键，可提供有关 schema 设计的元数据。主键意味着其他表可将此列集用作行的唯一标识符。可以为一个表指定一个主键，作为列约束或表约束。主键约束指定的列集应不同于为同一表定义的任何唯一约束指定的其他列集。  
PRIMARY KEY 列也定义为 NOT NULL。  
主键约束仅为信息性的。这些约束不由系统强制实施，而是由计划程序使用。

References *reftable* [ ( *refcolumn* ) ]  
一个指定外键约束的子句，该外键约束暗示列包含的值必须与被引用表的某个行的被引用列中的值匹配。被引用列应为引用的表中的唯一或主键约束的列。  
 外键约束仅为信息性的。这些约束不由系统强制实施，而是由计划程序使用。

LIKE *parent\$1table* [ \$1 INCLUDING \$1 EXCLUDING \$1 DEFAULTS ]   <a name="create-table-like"></a>
一个指定现有表的子句，新表自动从该表中复制列名、数据类型和 NOT NULL 约束。新表和父表是分离的，对父表所做的所有更改都不适用于新表。仅在指定 INCLUDING DEFAULTS 的情况下复制已复制列定义的默认表达式。默认行为是排除默认表达式，以便新表的所有列包含 null 默认值。  
使用 LIKE 选项创建的表不继承主键约束和外键约束。分配样式、排序键、BACKUP 和 NULL 属性由 LIKE 表继承，但您无法在 CREATE TABLE ... LIKE 语句中明确设置这些 属性。

BACKUP \$1 YES \$1 NO \$1   <a name="create-table-backup"></a>
一个子句，指定表是否应包含在自动和手动集群快照中。  
对于不会包含关键数据的表（如暂存表），请指定 BACKUP NO 以节省在创建快照并从快照还原时的处理时间，从而减小在 Amazon Simple Storage Service 上占用的存储空间。BACKUP NO 设置不会影响数据自动复制到集群内的其他节点，因此当发生节点故障时，指定了 BACKUP NO 的表将被还原。默认值为 BACKUP YES。  
RA3 预调配集群和 Amazon Redshift Serverless 工作组不支持无备份表。在 RA3 集群和 Serverless 工作组中标记为无备份的表将被视为永久表，在拍摄快照时将始终对其进行备份，并在从快照还原时还原该表。要避免无备份表产生快照成本，请在拍摄快照之前将其截断。

DISTSTYLE \$1 AUTO \$1 EVEN \$1 KEY \$1 ALL \$1  
定义整个表的数据分配样式的关键词。Amazon Redshift 会根据为表指定的分配样式将表行分配给计算节点。默认值为 AUTO。  
为表选择的分配样式将影响数据库的整体性能。有关更多信息，请参阅 [用于优化查询的数据分配](t_Distributing_data.md)。可能的分配样式如下：  
+ AUTO：Amazon Redshift 可基于表数据指定最佳分配方式。例如，如果指定 AUTO 分配方式，Amazon Redshift 最初向小型表指定的是 ALL 分配方式。当表变大时，Amazon Redshift 可能会将分配方式更改为 KEY，选择主键（或复合主键的列）作为 DISTKEY。如果表变大且没有任何一列适合用作 DISTKEY，Amazon Redshift 会将分配方式更改为 EVEN。分配方式的更改在后台进行，对用户查询的影响极小。

  要查看应用于表的分配方式，请查询 PG\$1CLASS 系统目录表。有关更多信息，请参阅 [查看分配方式](viewing-distribution-styles.md)。
+ EVEN：表中的数据在轮询分配中跨集群中的节点均匀分布。行 ID 用来确定分配，并且为每个节点分配的行数大致相同。
+ KEY：按 DISTKEY 列中的值分配数据。在您将联接表的联接列设置为分配键时，来自这两个表的联接行将在计算节点上并置。在并置数据时，优化程序可更高效地执行联接。如果您指定 DISTSTYLE KEY，则必须为表指定 DISTKEY 列或者将此列指定为列定义的一部分。有关更多信息，请参阅本主题前面的 DISTKEY 参数。
+  ALL：向每个节点分配整个表的副本。此分配样式可确保任何联接所需的所有行在每个节点上都可用，但这将使存储要求成倍提高，并且会增加表的加载和维护次数。将 ALL 分配样式用于 KEY 分配不适用的部分维度表时会缩短执行时间，但必须针对维护成本来权衡性能改进。

DISTKEY ( *column\$1name* )  
一个约束，指定要用作表的分配键的列。可在列名后使用 DISTKEY 关键字，也可使用 DISTKEY (*column\$1name*) 语法将该关键字用作表定义的一部分。每种方法的效果相同。有关更多信息，请参阅本主题前面的 DISTSTYLE 参数。

[COMPOUND \$1 INTERLEAVED ] SORTKEY (* column\$1name* [,...]) \$1 [ SORTKEY AUTO ]  
为表指定一个或多个排序键。在数据加载到表中后，将按指定为排序键的列对数据进行排序。可在列名后使用 SORTKEY 关键字来指定单列排序键，也可使用 `SORTKEY (column_name [ , ... ] )` 语法将一个或多个列指定为表的排序键列。  
您可以选择指定 COMPOUND 或 INTERLEAVED 排序样式。如果使用列指定 SORTKEY，则默认值为 COMPOUND。有关更多信息，请参阅 [排序键](t_Sorting_data.md)。  
如果您不指定任何排序键选项，则默认设置为 AUTO。  
最多可以为每个表定义 400 个 COMPOUND SORTKEY 列或 8 个 INTERLEAVED SORTKEY 列。    
AUTO  
指定 Amazon Redshift 会基于表数据分配最佳排序键。例如，如果指定了 AUTO 排序键，Amazon Redshift 最初不会为表分配排序键。如果 Amazon Redshift 确定排序键将提高查询的性能，那么 Amazon Redshift 可能会更改您的表的排序键。表的实际排序通过自动表排序完成。有关更多信息，请参阅 [自动表排序](t_Reclaiming_storage_space202.md#automatic-table-sort)。  
Amazon Redshift 不会修改具有现有排序键或分配键的表。一个例外情况是，如果表具有从未在 JOIN 中使用过的分配键，则可能会在 Amazon Redshift 确定有更好的键时更改键。  
要查看表的排序键，请查询 SVV\$1TABLE\$1INFO 系统目录视图。有关更多信息，请参阅 [SVV\$1TABLE\$1INFO](r_SVV_TABLE_INFO.md)。要查看 Amazon Redshift Advisor 对表的建议，请查询 SVV\$1ALTER\$1TABLE\$1RECOMMENDATIONS 系统目录视图。有关更多信息，请参阅 [SVV\$1ALTER\$1TABLE\$1RECOMMENDATIONS](r_SVV_ALTER_TABLE_RECOMMENDATIONS.md)。要查看 Amazon Redshift 所采取的操作，请查询 SVL\$1AUTO\$1WORKER\$1ACTION 系统目录视图。有关更多信息，请参阅 [SVL\$1AUTO\$1WORKER\$1ACTION](r_SVL_AUTO_WORKER_ACTION.md)。  
COMPOUND  
指定使用由所有列出的列构成的复合键按这些列的列出顺序对数据进行排序。当查询根据排序列的顺序扫描行时，复合排序键最有用。当查询依赖辅助排序列时，使用复合键进行排序所带来的性能好处会减少。您最多可以为每个表定义 400 个 COMPOUND SORTKEY 列。  
INTERLEAVED  
指定使用交错排序键对数据进行排序。可以为一个交错排序键最多指定 8 个列。  
交错排序为排序键中的每个列或列子集提供了相同的权重，以便查询不会依赖列在排序键中的顺序。当查询使用一个或多个辅助排序列时，交错排序会大大提高查询性能。交错排序产生的数据加载和 vacuum 操作的开销成本较低。  
不要在具有单调递增属性的列（例如，身份列、日期或时间戳）上使用交错排序键。

ENCODE AUTO   
使 Amazon Redshift 能够自动调整表中所有列的编码类型，以优化查询性能。ENCODE AUTO 会保留您在创建表时指定的初始编码类型。然后，如果 Amazon Redshift 确定新的编码类型可以提高查询性能，则 Amazon Redshift 可以更改表列的编码类型。如果不在表中的任何列上指定编码类型，则 ENCODE AUTO 是默认设置。

UNIQUE ( *column\$1name* [,...] )  
一个约束，指定包含一个或多个表列的组只能包含唯一值。唯一表约束的行为与列约束的行为相同，但前者能够跨多个列。在唯一约束的上下文中，null 值不被视为相同。每个唯一表约束指定的列集必须不同于由为表定义的任何其他唯一键约束或主键约束指定的列集。  
 唯一约束是信息性的，而不由系统强制实施。

PRIMARY KEY ( *column\$1name* [,...] )  
一个约束，指定表的一个列或大量列只能包含唯一（不重复）的非 null 值。通过将一个列集标识为主键，也会提供有关 schema 设计的元数据。主键意味着其他表可将此列集用作行的唯一标识符。可以为一个表指定一个主键，作为单个列约束或表约束。主键约束指定的列集应不同于为同一表定义的任何唯一约束指定的其他列集。  
 主键约束仅为信息性的。这些约束不由系统强制实施，而是由计划程序使用。

FOREIGN KEY ( *column\$1name* [, ... ] ) REFERENCES *reftable* [ ( *refcolumn* ) ]   
一个指定外键约束的约束，该约束要求新表的一个或多个列只能包含与被引用表的某个行的一个或多个被引用列中的值匹配的值。如果忽略 *refcolumn*，则使用 *reftable* 的主键。被引用列必须为被引用表中的唯一或主键约束的列。  
外键约束仅为信息性的。这些约束不由系统强制实施，而是由计划程序使用。

## 使用说明
<a name="r_CREATE_TABLE_usage"></a>

唯一键、主键和外键约束仅供参考；在您填充表时，*Amazon Redshift* 并不强制实施它们。例如，如果您将数据插入到具有依赖关系的表中，即使插入操作违反了约束，插入也会成功。但是，主键和外键用作规划提示，如果您应用程序中的 ETL 处理或其他一些处理强制其完整性，则应声明它们。有关如何删除具有依赖关系的表的信息，请参阅 [DROP TABLE](r_DROP_TABLE.md)。

### 限制和配额
<a name="r_CREATE_TABLE_usage-limits"></a>

创建表时，请考虑以下限制。
+ 集群中按节点类型的最大表数有限制。有关更多信息，请参阅《Amazon Redshift 管理指南》**中的[限制](https://docs.aws.amazon.com/redshift/latest/mgmt/amazon-redshift-limits.html)。
+ 表名的最大字符数为 127。
+ 可在单个表中定义的列的最大数目为 1,600。
+ 可在单个表中定义的 SORTKEY 列的最大数目为 400。

### 列级设置和表级设置摘要
<a name="r_CREATE_TABLE_usage-summary_of_settings"></a>

 可在列级或表级设置若干属性和设置。在某些情况下，在列级或表级设置属性或约束的效果相同。在其他情况下，它们会产生不同的结果。

 下面的列表汇总了列级和表级设置：

DISTKEY  
无论是在列级设置还是在表级设置，效果是相同的。  
如果在列级或表级设置 DISTKEY，则 DISTSTYLE 必须设置为 KEY 或者根本不设置 DISTSTYLE。只能在表级设置 DISTSTYLE。

SORTKEY  
如果在列级进行设置，则 SORTKEY 必须为单个列。如果在表级设置 SORTKEY，则一个或多个列可构成复合或交错复合排序键。

COLLATE CASE\$1SENSITIVE \$1 COLLATE CASE\$1INSENSITIVE  
Amazon Redshift 不支持更改列的区分大小写配置。将新列附加到表时，Amazon Redshift 对区分大小写使用默认值。在附加新列时，Amazon Redshift 不支持 COLLATE 关键字。  
有关如何使用数据库排序规则创建数据库的信息，请参阅[CREATE DATABASE](r_CREATE_DATABASE.md)。  
有关 COLLATE 函数的信息，请参阅[COLLATE 函数](r_COLLATE.md)。

UNIQUE  
在列级别，可将一个或多个键设置为 UNIQUE；UNIQUE 约束分别应用于每个列。如果在表级设置 UNIQUE，则一个或多个列可构成复合 UNIQUE 约束。

PRIMARY KEY  
如果在列级进行设置，则 PRIMARY KEY 必须为单个列。如果在表级设置 PRIMARY KEY，则一个或多个列可构成复合主键。

FOREIGN KEY  
无论是在列级设置还是在表级设置 FOREIGN KEY，效果是相同的。在列级别，语法为 `REFERENCES` *reftable* [ ( *refcolumn* )]。

### 分配传入数据
<a name="r_CREATE_TABLE_usage-distribution-of-incoming-data"></a>

如果传入数据的哈希分配方案与目标表的哈希分配方案匹配，则在加载数据时，没有实际必要的数据物理分配。例如，如果为新表设置分配键并从相同键列上分配的另一个表中插入数据，则使用相同的节点和切片就地加载数据。不过，如果源表和目标表都设置为 EVEN 分配，则数据将重新分配到目标表。

### 宽表
<a name="r_CREATE_TABLE_usage-wide-tables"></a>

您也许能够创建很宽的表，但无法对表执行查询处理，例如 INSERT 或 SELECT 语句。具有宽度固定的列（例如 CHAR）的表的最大宽度为 64KB - 1（即 65535 字节）。如果表包含 VARCHAR 列，则表可以具有更大的声明宽度，而不会返回错误，因为 VARCHARS 列不会将其完全声明的宽度计入计算出的查询处理限制。针对 VARCHAR 列的有效查询处理限制将因大量因素而异。

如果表对于插入或选择操作来说太宽，您将收到以下错误。

```
ERROR:  8001
DETAIL:  The combined length of columns processed in the SQL statement
exceeded the query-processing limit of 65535 characters (pid:7627)
```

## 示例
<a name="r_CREATE_TABLE_usage-examples"></a>

有关说明 CREATE TABLE 命令用法的示例，请参阅[示例](r_CREATE_TABLE_examples.md) 主题。

# 示例
<a name="r_CREATE_TABLE_examples"></a>

以下示例演示 Amazon Redshift CREATE TABLE 语句中的各种列和表属性。有关 CREATE TABLE 的更多信息，包括参数定义，请参阅 [CREATE TABLE](r_CREATE_TABLE_NEW.md)。

许多示例使用来自 *TICKIT* 示例数据集的表和数据。有关更多信息，请参阅[示例数据库](https://docs.aws.amazon.com/redshift/latest/dg/c_sampledb.html)。

 在 CREATE TABLE 命令中，您可以使用数据库名称和架构名称作为表名称前缀。例如，`dev_database.public.sales`。数据库名称必须是您已连接到的数据库。在其他数据库中创建数据库对象的任何尝试都会失败，并出现无效的操作错误。

## 使用分配键、复合排序键和压缩创建表
<a name="r_CREATE_TABLE_examples-create-a-table-with-distribution-key"></a>

以下示例利用为多个列定义的压缩在 TICKIT 数据库中创建 SALES 表。LISTID 声明为分配键，LISTID 和 SELLERID 声明为多列复合排序键。还为表定义了主键约束和外键约束。创建示例中的表之前，如果不存在约束，则可能需要向外键引用的每个列添加 UNIQUE 约束。

```
create table sales(
salesid integer not null,
listid integer not null,
sellerid integer not null,
buyerid integer not null,
eventid integer not null encode mostly16,
dateid smallint not null,
qtysold smallint not null encode mostly8,
pricepaid decimal(8,2) encode delta32k,
commission decimal(8,2) encode delta32k,
saletime timestamp,
primary key(salesid),
foreign key(listid) references listing(listid),
foreign key(sellerid) references users(userid),
foreign key(buyerid) references users(userid),
foreign key(dateid) references date(dateid))
distkey(listid)
compound sortkey(listid,sellerid);
```

结果如下：

```
schemaname | tablename | column     | type                        | encoding | distkey | sortkey | notnull
-----------+-----------+------------+-----------------------------+----------+---------+---------+--------
public     | sales     | salesid    | integer                     | lzo      | false   |       0 | true
public     | sales     | listid     | integer                     | none     | true    |       1 | true
public     | sales     | sellerid   | integer                     | none     | false   |       2 | true
public     | sales     | buyerid    | integer                     | lzo      | false   |       0 | true
public     | sales     | eventid    | integer                     | mostly16 | false   |       0 | true
public     | sales     | dateid     | smallint                    | lzo      | false   |       0 | true
public     | sales     | qtysold    | smallint                    | mostly8  | false   |       0 | true
public     | sales     | pricepaid  | numeric(8,2)                | delta32k | false   |       0 | false
public     | sales     | commission | numeric(8,2)                | delta32k | false   |       0 | false
public     | sales     | saletime   | timestamp without time zone | lzo      | false   |       0 | false
```

以下示例使用不区分大小写的列 col1 创建表 t1。

```
create table T1 (
  col1 Varchar(20) collate case_insensitive
 );
            
insert into T1 values ('bob'), ('john'), ('Tom'), ('JOHN'), ('Bob');
```

查询表：

```
select * from T1 where col1 = 'John';
   
col1
------
 john
 JOHN
(2 rows)
```

## 使用交错排序键创建表
<a name="CREATE_TABLE_NEW-create-a-table-using-interleaved-sortkey"></a>

以下示例使用交错排序键创建 CUSTOMER 表。

```
create table customer_interleaved (
  c_custkey     	integer        not null,
  c_name        	varchar(25)    not null,
  c_address     	varchar(25)    not null,
  c_city        	varchar(10)    not null,
  c_nation      	varchar(15)    not null,
  c_region      	varchar(12)    not null,
  c_phone       	varchar(15)    not null,
  c_mktsegment      varchar(10)    not null)
diststyle all
interleaved sortkey (c_custkey, c_city, c_mktsegment);
```

## 使用 IF NOT EXISTS 创建表
<a name="CREATE_TABLE_NEW-create-a-table-using-if-not-exists"></a>

 以下示例创建 CITIES 表，如果该表已存在，则不执行任何操作并返回一条消息：

```
create table if not exists cities(
cityid integer not null,
city varchar(100) not null,
state char(2) not null);
```

## 使用 ALL 分配创建表
<a name="CREATE_TABLE_NEW-create-a-table-with-all-distribution"></a>

 以下示例使用 ALL 分配创建 VENUE 表。

```
create table venue(
venueid smallint not null,
venuename varchar(100),
venuecity varchar(30),
venuestate char(2),
venueseats integer,
primary key(venueid))
diststyle all;
```

## 使用 EVEN 分配创建表
<a name="r_CREATE_TABLE_NEW-create-a-table-with-default-even-distribution"></a>

以下示例创建一个包含三个列的名为 MYEVENT 的表。

```
create table myevent(
eventid int,
eventname varchar(200),
eventcity varchar(30))
diststyle even;
```

均匀分配表，并且不对表进行排序。表没有声明的 DISTKEY 或 SORTKEY 列。

```
select "column", type, encoding, distkey, sortkey
from pg_table_def where tablename = 'myevent';
            
  column   |          type          | encoding | distkey | sortkey
-----------+------------------------+----------+---------+---------
 eventid   | integer                | lzo      | f       |       0
 eventname | character varying(200) | lzo      | f       |       0
 eventcity | character varying(30)  | lzo      | f       |       0
(3 rows)
```

## 创建与另一个表类似的临时表
<a name="r_CREATE_TABLE_NEW-create-a-temporary-table-that-is-like-another-table"></a>

以下示例创建一个名为“TEMPEVENT”的临时表，该表从 EVENT 表继承其列。

```
create temp table tempevent(like event); 
```

此表还继承其父表的 DISTKEY 和 SORTKEY 属性：

```
select "column", type, encoding, distkey, sortkey
 from pg_table_def where tablename = 'tempevent';

  column   |            type             | encoding | distkey | sortkey
-----------+-----------------------------+----------+---------+---------
 eventid   | integer                     | none     | t       |       1
 venueid   | smallint                    | none     | f       |       0
 catid     | smallint                    | none     | f       |       0
 dateid    | smallint                    | none     | f       |       0
 eventname | character varying(200)      | lzo      | f       |       0
 starttime | timestamp without time zone | bytedict | f       |       0
(6 rows)
```

## 创建具有 IDENTITY 列的表
<a name="r_CREATE_TABLE_NEW-create-a-table-with-an-identity-column"></a>

以下示例创建一个名为 VENUE\$1IDENT 的表，该表具有名为 VENUEID 的 IDENTITY 列。该列从 0 开始，并为每个记录增加 1。VENUEID 还被声明为表的主键。

```
create table venue_ident(venueid bigint identity(0, 1),
venuename varchar(100),
venuecity varchar(30),
venuestate char(2),
venueseats integer,
primary key(venueid));
```

## 创建具有默认 IDENTITY 列的表
<a name="r_CREATE_TABLE_NEW-create-a-table-with-default-identity-column"></a>

下面的示例创建了一个名为 `t1` 的表。此表拥有名为 `hist_id` 的 IDENTITY 列和名为 `base_id` 的默认 IDENTITY 列。

```
CREATE TABLE t1(
  hist_id BIGINT IDENTITY NOT NULL, /* Cannot be overridden */
  base_id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, /* Can be overridden */
  business_key varchar(10) ,
  some_field varchar(10)
);
```

在表中插入一行，表明 `hist_id` 和 `base_id` 值均已生成。

```
INSERT INTO T1 (business_key, some_field) values ('A','MM');
```

```
SELECT * FROM t1;

 hist_id | base_id | business_key | some_field
---------+---------+--------------+------------
       1 |       1 | A            | MM
```

插入第二行，表明 `base_id` 的默认值已生成。

```
INSERT INTO T1 (base_id, business_key, some_field) values (DEFAULT, 'B','MNOP');
```

```
SELECT * FROM t1;

 hist_id | base_id | business_key | some_field
---------+---------+--------------+------------
       1 |       1 | A            | MM
       2 |       2 | B            | MNOP
```

插入第三行，表明 `base_id` 的值不需要是唯一的。

```
INSERT INTO T1 (base_id, business_key, some_field) values (2,'B','MNNN');
```

```
SELECT * FROM t1;
            
 hist_id | base_id | business_key | some_field
---------+---------+--------------+------------
       1 |       1 | A            | MM
       2 |       2 | B            | MNOP
       3 |       2 | B            | MNNN
```

## 创建具有 DEFAULT 列值的表
<a name="r_CREATE_TABLE_NEW-create-a-table-with-default-column-values"></a>

以下示例创建一个 CATEGORYDEF 表，该表声明每个列的默认值：

```
create table categorydef(
catid smallint not null default 0,
catgroup varchar(10) default 'Special',
catname varchar(10) default 'Other',
catdesc varchar(50) default 'Special events',
primary key(catid));
            
insert into categorydef values(default,default,default,default);
```

```
select * from categorydef;
            
 catid | catgroup | catname |    catdesc
-------+----------+---------+----------------
     0 | Special  | Other   | Special events
(1 row)
```

## DISTSTYLE、DISTKEY 和 SORTKEY 选项
<a name="r_CREATE_TABLE_NEW-diststyle-distkey-and-sortkey-options"></a>

以下示例显示 DISTKEY、SORTKEY 和 DISTSTYLE 选项的工作方式。在此示例中，COL1 是分配键；因此，必须将分配样式设置为 KEY 或不设置分配样式。默认情况下，该表没有排序键，所以不会进行排序：

```
create table t1(col1 int distkey, col2 int) diststyle key;
```

```
select "column", type, encoding, distkey, sortkey
from pg_table_def where tablename = 't1';

column |  type   | encoding | distkey | sortkey
-------+---------+----------+---------+---------
col1   | integer | az64     | t       | 0
col2   | integer | az64     | f       | 0
```

在以下示例中，将同一个列定义为分配键和排序键。同样，必须将分配样式设置为 KEY 或者不设置分配样式。

```
create table t2(col1 int distkey sortkey, col2 int);
```

```
select "column", type, encoding, distkey, sortkey
from pg_table_def where tablename = 't2';
            
column |  type   | encoding | distkey | sortkey
-------+---------+----------+---------+---------
col1   | integer | none     | t       | 1
col2   | integer | az64     | f       | 0
```

在以下示例中，未将任何列设置为分配键，COL2 设置为排序键，分配键设置为 ALL：

```
create table t3(col1 int, col2 int sortkey) diststyle all;
```

```
select "column", type, encoding, distkey, sortkey
from pg_table_def where tablename = 't3';
            
Column |  Type   | Encoding | DistKey | SortKey
-------+---------+----------+---------+--------
col1   | integer | az64     | f       | 0
col2   | integer | none     | f       | 1
```

在以下示例中，分配样式设置为 EVEN，并且未显式定义排序键；因此，表将均匀分配而不进行排序。

```
create table t4(col1 int, col2 int) diststyle even;
```

```
select "column", type, encoding, distkey, sortkey
from pg_table_def where tablename = 't4';
            
             column |  type   |encoding | distkey | sortkey
--------+---------+---------+---------+--------
col1    | integer | az64    | f       | 0
col2    | integer | az64    | f       | 0
```

## 使用 ENCODE AUTO 选项创建表
<a name="r_CREATE_TABLE_NEW-create-a-table-with-encode-option"></a>

下面的示例使用自动压缩编码创建表 `t1`。不为任何列指定编码类型时，ENCODE AUTO 是表的默认设置。

```
create table t1(c0 int, c1 varchar);
```

下面的示例通过指定 ENCODE AUTO 使用自动压缩编码创建表 `t2`。

```
create table t2(c0 int, c1 varchar) encode auto;
```

下面的示例通过指定 ENCODE AUTO 使用自动压缩编码创建表 `t3`。列 `c0` 是用 DELTA 的初始编码类型定义的。如果另一个编码可以提供更好的查询性能，则 Amazon Redshift 可以更改编码。

```
create table t3(c0 int encode delta, c1 varchar) encode auto;
```

下面的示例通过指定 ENCODE AUTO 使用自动压缩编码创建表 `t4`。列 `c0` 使用 DELTA 的初始编码进行定义，而列 `c1` 则是用 LZO 的初始编码定义的。如果另一个编码可以提供更好的查询性能，则 Amazon Redshift 可以更改这些编码。

```
create table t4(c0 int encode delta, c1 varchar encode lzo) encode auto;
```

# CREATE TABLE AS
<a name="r_CREATE_TABLE_AS"></a>

**Topics**
+ [语法](#r_CREATE_TABLE_AS-synopsis)
+ [参数](#r_CREATE_TABLE_AS-parameters)
+ [CTAS 使用说明](r_CTAS_usage_notes.md)
+ [CTAS 示例](r_CTAS_examples.md)

创建基于查询的新表。此表的所有者为发出命令的用户。

新表与命令的查询定义的数据一起加载。表列具有与查询的输出列关联的名称和数据类型。CREATE TABLE AS (CTAS) 命令创建一个新表并评估查询以加载新表。

## 语法
<a name="r_CREATE_TABLE_AS-synopsis"></a>

```
CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ]
TABLE table_name
[ ( column_name [, ... ] ) ]
[ BACKUP { YES | NO } ]
[ table_attributes ]
AS query

where table_attributes are:
[ DISTSTYLE { AUTO | EVEN | ALL | KEY } ]
[ DISTKEY( distkey_identifier ) ]
[ [ COMPOUND | INTERLEAVED ] SORTKEY( column_name [, ...] ) ]
```

## 参数
<a name="r_CREATE_TABLE_AS-parameters"></a>

LOCAL   
虽然语句中接受此可选关键词，但它在 Amazon Redshift 中没有任何作用。

TEMPORARY \$1 TEMP   
创建一个临时表。在创建临时表的会话结束时将自动删除该临时表。

 *table\$1name*   
要创建的表的名称。  
如果指定以“\$1”开始的表名，表会创建为临时表。例如：  

```
create table #newtable (id) as select * from oldtable;
```
表名称的最大长度为 127 个字节；更长的名称将被截断为 127 个字节。Amazon Redshift 会按节点类型强制执行每个集群的表数量配额。可使用数据库和 schema 名称限定表名，如下表所示。  

```
create table tickit.public.test (c1) as select * from oldtable;
```
在此示例中，`tickit` 为数据库名称，`public` 为 schema 名称。如果数据库或 schema 不存在，此语句将返回错误。  
如果提供 schema 名称，则在该 schema 中创建新表（假定创建者有权访问 schema）。表名称必须是该 schema 中的唯一名称。如果未指定 schema，则可使用当前数据库 schema 创建表。如果您创建的是临时表，则无法指定 schema 名称，因为特定 schema 中存在临时表。  
如果多个同名临时表是在单独的会话中创建的，则这些同名临时表能够同时存在于同一个数据库中。这些表将分配给不同的 schemas。

 *column\$1name*   
新表中的列的名称。如果没有提供列名，则采用查询的输出列名中的列名。默认列名用于表达式。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。

BACKUP \$1 YES \$1 NO \$1   
一个子句，指定表是否应包含在自动和手动集群快照中。  
对于不会包含关键数据的表（如暂存表），请指定 BACKUP NO 以节省在创建快照并从快照还原时的处理时间，从而减小在 Amazon Simple Storage Service 上占用的存储空间。BACKUP NO 设置不会影响数据到集群内的其他节点的自动复制，因此当发生节点故障时，指定了 BACKUP NO 的表将被还原。默认值为 BACKUP YES。  
RA3 预调配集群和 Amazon Redshift Serverless 工作组不支持无备份表。在 RA3 集群和 Serverless 工作组中标记为无备份的表将被视为永久表，在拍摄快照时将始终对其进行备份，并在从快照还原时还原该表。要避免无备份表产生快照成本，请在拍摄快照之前将其截断。

DISTSTYLE \$1 AUTO \$1 EVEN \$1 KEY \$1 ALL \$1  
定义整个表的数据分配样式的关键词。Amazon Redshift 会根据为表指定的分配样式将表行分配给计算节点。默认值为 DISTSTYLE AUTO。  
为表选择的分配样式将影响数据库的整体性能。有关更多信息，请参阅 [用于优化查询的数据分配](t_Distributing_data.md)。  
+ AUTO：Amazon Redshift 可基于表数据指定最佳分配方式。要查看应用于表的分配方式，请查询 PG\$1CLASS 系统目录表。有关更多信息，请参阅 [查看分配方式](viewing-distribution-styles.md)。
+ EVEN：表中的数据在轮询分配中跨集群中的节点均匀分布。行 ID 用来确定分配，并且为每个节点分配的行数大致相同。这是默认分配方法。
+ KEY：按 DISTKEY 列中的值分配数据。在您将联接表的联接列设置为分配键时，来自这两个表的联接行将在计算节点上并置。在并置数据时，优化程序可更高效地执行联接。如果您指定 DISTSTYLE KEY，则必须命名 DISTKEY 列。
+  ALL：向每个节点分配整个表的副本。此分配样式可确保任何联接所需的所有行在每个节点上都可用，但这将使存储要求成倍提高，并且会增加表的加载和维护次数。将 ALL 分配样式用于 KEY 分配不适用的部分维度表时会缩短执行时间，但必须针对维护成本来权衡性能改进。

DISTKEY (*column*)  
指定分配键的列名或位置号。使用在表的可选列列表或所选查询列表中指定的名称。或者，使用位置号，其中所选的第一列为 1，所选的第二列为 2，以此类推。一个表中只能有一个列可成为分配键：  
+ 如果将一个列声明为 DISTKEY 列，则必须将 DISTSTYLE 设置为 KEY 或者根本不设置 DISTSTYLE。
+ 如果未声明 DISTKEY 列，则可将 DISTSTYLE 设置为 EVEN。
+ 如果您不指定 DISTKEY 或 DISTSTYLE，CTAS 会根据 SELECT 子句的查询计划确定新表的分配样式。有关更多信息，请参阅 [继承列和表属性](r_CTAS_usage_notes.md#r_CTAS_usage_notes-inheritance-of-column-and-table-attributes)。
您可以将同一个列定义为分配键和排序键；此方法旨在当有问题的列为查询中的联接列时加速联接。

[ COMPOUND \$1 INTERLEAVED ] SORTKEY ( *column\$1name* [, ... ] )  
为表指定一个或多个排序键。在数据加载到表中后，将按指定为排序键的列对数据进行排序。  
您可以选择指定 COMPOUND 或 INTERLEAVED 排序样式。默认为 COMPOUND。有关更多信息，请参阅 [排序键](t_Sorting_data.md)。  
最多可以为每个表定义 400 个 COMPOUND SORTKEY 列或 8 个 INTERLEAVED SORTKEY 列。  
如果您不指定 SORTKEY，CTAS 会根据 SELECT 子句的查询计划的新表排序键。有关更多信息，请参阅 [继承列和表属性](r_CTAS_usage_notes.md#r_CTAS_usage_notes-inheritance-of-column-and-table-attributes)。    
COMPOUND  
指定使用由所有列出的列构成的复合键按这些列的列出顺序对数据进行排序。当查询根据排序列的顺序扫描行时，复合排序键最有用。当查询依赖辅助排序列时，使用复合键进行排序所带来的性能好处会减少。您最多可以为每个表定义 400 个 COMPOUND SORTKEY 列。  
INTERLEAVED  
指定使用交错排序键对数据进行排序。可以为一个交错排序键最多指定 8 个列。  
交错排序为排序键中的每个列或列子集提供了相同的权重，以便查询不会依赖列在排序键中的顺序。当查询使用一个或多个辅助排序列时，交错排序会大大提高查询性能。交错排序产生的数据加载和 vacuum 操作的开销成本较低。

AS *query*   
Amazon Redshift 支持的任何查询（SELECT 语句）。

# CTAS 使用说明
<a name="r_CTAS_usage_notes"></a>

## 限制
<a name="r_CTAS_usage_notes-limits"></a>

Amazon Redshift 会按节点类型强制执行每个集群的表数量配额。

表名的最大字符数为 127。

可在单个表中定义的列的最大数目为 1,600。

## 继承列和表属性
<a name="r_CTAS_usage_notes-inheritance-of-column-and-table-attributes"></a>

CREATE TABLE AS (CTAS) 表不从其父表继承约束、身份列、默认列值或主键。

您不能为 CTAS 表指定列压缩编码。Amazon Redshift 自动分配压缩编码，如下所示：
+ 为定义为排序键的列分配 RAW 压缩。
+ 定义为 BOOLEAN、REAL、DOUBLE PRECISION、GEOMETRY 或 GEOGRAPHY 数据类型的列分配了 RAW 压缩。
+ 定义为 SMALLINT、INTEGER、BIGINT、DECIMAL、DATE、TIME、TIMETZ、TIMESTAMP 或 TIMESTAMPTZ 的列分配了 AZ64 压缩。
+ 定义为 CHAR、VARCHAR 或 VARBYTE 的列分配了 LZO 压缩。

有关更多信息，请参阅[压缩编码](c_Compression_encodings.md)和[数据类型](c_Supported_data_types.md)。

要显式分配列编码，请使用 [CREATE TABLE](r_CREATE_TABLE_NEW.md)。

CTAS 根据 SELECT 子句的查询计划确定新表的分配样式和排序键。

对于复杂查询，如包含连接、聚合、ORDER BY 子句或 LIMIT 子句，CTAS 会尽最大努力基于查询计划选择最佳分配样式和分类键。

**注意**  
对于使用大型数据集或复杂查询实现最佳性能，我们建议使用典型数据集进行测试。

通常，您可以通过检查查询计划查看查询优化器选择哪些列（如果有）进行数据排序和分配，预测 CTAS 将选择哪个分配键和分类键。如果查询计划的顶端节点为一个表（XN 顺序扫描）的简单顺序扫描，则 CTAS 通常使用源表的分配样式和分类键。如果查询计划的顶部节点是除顺序扫描外的任何情况（如 XN 限制、XN 排序、XN HashAggregate 等），CTAS 会尽最大努力根据查询计划选择最佳分配样式和分类键。

例如，假设您使用 SELECT 子句创建了以下五个表：
+ 简单的 SELECT 语句 
+ Limit 子句 
+ 使用 LISTID 的 ORDER BY 子句 
+ 使用 QTYSOLD 的 ORDER BY 子句 
+ 使用 GROUP BY 子句的 SUM 聚合函数。

以下示例显示每个 CTAS 语句的查询计划。

```
explain create table sales1_simple as select listid, dateid, qtysold from sales;
                           QUERY PLAN
----------------------------------------------------------------
 XN Seq Scan on sales  (cost=0.00..1724.56 rows=172456 width=8)
(1 row)


explain create table sales2_limit as select listid, dateid, qtysold from sales limit 100;
                              QUERY PLAN
----------------------------------------------------------------------
 XN Limit  (cost=0.00..1.00 rows=100 width=8)
   ->  XN Seq Scan on sales  (cost=0.00..1724.56 rows=172456 width=8)
(2 rows)


explain create table sales3_orderbylistid as select listid, dateid, qtysold from sales order by listid;
                               QUERY PLAN
------------------------------------------------------------------------
 XN Sort  (cost=1000000016724.67..1000000017155.81 rows=172456 width=8)
   Sort Key: listid
   ->  XN Seq Scan on sales  (cost=0.00..1724.56 rows=172456 width=8)
(3 rows)


explain create table sales4_orderbyqty as select listid, dateid, qtysold from sales order by qtysold;
                               QUERY PLAN
------------------------------------------------------------------------
 XN Sort  (cost=1000000016724.67..1000000017155.81 rows=172456 width=8)
   Sort Key: qtysold
   ->  XN Seq Scan on sales  (cost=0.00..1724.56 rows=172456 width=8)
(3 rows)


explain create table sales5_groupby as select listid, dateid, sum(qtysold) from sales group by listid, dateid;
                              QUERY PLAN
----------------------------------------------------------------------
 XN HashAggregate  (cost=3017.98..3226.75 rows=83509 width=8)
   ->  XN Seq Scan on sales  (cost=0.00..1724.56 rows=172456 width=8)
(2 rows)
```

要查看每个表的分配键和分类键，请查询 PG\$1TABLE\$1DEF 系统目录表，如下所示。

```
select * from pg_table_def where tablename like 'sales%';

      tablename       |   column   | distkey | sortkey
----------------------+------------+---------+---------
 sales                | salesid    | f       |       0
 sales                | listid     | t       |       0
 sales                | sellerid   | f       |       0
 sales                | buyerid    | f       |       0
 sales                | eventid    | f       |       0
 sales                | dateid     | f       |       1
 sales                | qtysold    | f       |       0
 sales                | pricepaid  | f       |       0
 sales                | commission | f       |       0
 sales                | saletime   | f       |       0
 sales1_simple        | listid     | t       |       0
 sales1_simple        | dateid     | f       |       1
 sales1_simple        | qtysold    | f       |       0
 sales2_limit         | listid     | f       |       0
 sales2_limit         | dateid     | f       |       0
 sales2_limit         | qtysold    | f       |       0
 sales3_orderbylistid | listid     | t       |       1
 sales3_orderbylistid | dateid     | f       |       0
 sales3_orderbylistid | qtysold    | f       |       0
 sales4_orderbyqty    | listid     | t       |       0
 sales4_orderbyqty    | dateid     | f       |       0
 sales4_orderbyqty    | qtysold    | f       |       1
 sales5_groupby       | listid     | f       |       0
 sales5_groupby       | dateid     | f       |       0
 sales5_groupby       | sum        | f       |       0
```

下表汇总了结果。为简便起见，我们在说明计划中忽略了成本、行和宽度详细信息。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_CTAS_usage_notes.html)

您可以在 CTAS 语句中明确指定分配样式和分类键。例如，下面的语句使用 EVEN 分配创建了一个表并指定 SALESID 作为分类键。

```
create table sales_disteven
diststyle even
sortkey (salesid)
as
select eventid, venueid, dateid, eventname
from event;
```

## 压缩编码
<a name="r_CTAS_usage_notes_encoding"></a>

ENCODE AUTO 用作表的默认设置。Amazon Redshift 会自动管理表中所有列的压缩编码。

## 分配传入数据
<a name="r_CTAS_usage_notes-distribution-of-incoming-data"></a>

如果传入数据的哈希分配方案与目标表的哈希分配方案匹配，则在加载数据时，没有实际必要的数据物理分配。例如，如果为新表设置分配键并从相同键列上分配的另一个表中插入数据，则使用相同的节点和切片就地加载数据。不过，如果源表和目标表都设置为 EVEN 分配，则数据将重新分配到目标表。

## 自动 ANALYZE 操作
<a name="r_CTAS_usage_notes-automatic-analyze-operations"></a>

Amazon Redshift 自动分析您使用 CTAS 命令创建的表。在最初创建这些表时，您不需要对这些表运行 ANALYZE 命令。如果修改了这些表，则应通过用来分析其他表的方式来分析这些表。

# CTAS 示例
<a name="r_CTAS_examples"></a>

以下示例为 EVENT 表创建名为 EVENT\$1BACKUP 的表：

```
create table event_backup as select * from event;
```

生成的表继承 EVENT 表中的分配键和排序键。

```
select "column", type, encoding, distkey, sortkey
from pg_table_def where tablename = 'event_backup';

column    | type                        | encoding | distkey | sortkey
----------+-----------------------------+----------+---------+--------
catid     | smallint                    | none     | false   |       0
dateid    | smallint                    | none     | false   |       1
eventid   | integer                     | none     | true    |       0
eventname | character varying(200)      | none     | false   |       0
starttime | timestamp without time zone | none     | false   |       0
venueid   | smallint                    | none     | false   |       0
```

以下命令通过选择 EVENT 表中的四个列来创建一个名为 EVENTDISTSORT 的新表。新表按 EVENTID 进行分配并按 EVENTID 和 DATEID 进行排序：

```
create table eventdistsort
distkey (1)
sortkey (1,3)
as
select eventid, venueid, dateid, eventname
from event;
```

结果如下：

```
select "column", type, encoding, distkey, sortkey
from pg_table_def where tablename = 'eventdistsort';

column   |          type          | encoding | distkey | sortkey
---------+------------------------+----------+---------+-------
eventid   | integer               | none     | t       | 1
venueid   | smallint              | none     | f       | 0
dateid    | smallint              | none     | f       | 2
eventname | character varying(200)| none     | f       | 0
```

可通过对分配键和排序键使用列名来创建完全相同的表。例如：

```
create table eventdistsort1
distkey (eventid)
sortkey (eventid, dateid)
as
select eventid, venueid, dateid, eventname
from event;
```

以下语句对表应用 EVEN 分配，但不定义明确的排序键。

```
create table eventdisteven
diststyle even
as
select eventid, venueid, dateid, eventname
from event;
```

该表不继承 EVENT 表 (EVENTID) 中的排序键，因为已为新表指定 EVEN 分配。新表没有排序键和分配键。

```
select "column", type, encoding, distkey, sortkey
from pg_table_def where tablename = 'eventdisteven';

column    |          type          | encoding | distkey | sortkey
----------+------------------------+----------+---------+---------
eventid   | integer                | none     | f       | 0
venueid   | smallint               | none     | f       | 0
dateid    | smallint               | none     | f       | 0
eventname | character varying(200) | none     | f       | 0
```

以下语句应用 EVEN 分配并定义排序键：

```
create table eventdistevensort diststyle even sortkey (venueid)
as select eventid, venueid, dateid, eventname from event;
```

 生成的表具有排序键，但不具有分配键。

```
select "column", type, encoding, distkey, sortkey
from pg_table_def where tablename = 'eventdistevensort';

column    |          type          | encoding | distkey | sortkey
----------+------------------------+----------+---------+-------
eventid   | integer                | none     | f       | 0
venueid   | smallint               | none     | f       | 1
dateid    | smallint               | none     | f       | 0
eventname | character varying(200) | none     | f       | 0
```

以下语句基于来自传入数据（基于 EVENTID 列进行排序）的其他键列重新分配 EVENT 表，但不定义 SORTKEY 列；因此，不会对表进行排序。

```
create table venuedistevent distkey(venueid)
as select * from event;
```

结果如下：

```
select "column", type, encoding, distkey, sortkey
from pg_table_def where tablename = 'venuedistevent';

 column   |            type             | encoding | distkey | sortkey
----------+-----------------------------+----------+---------+-------
eventid   | integer                     | none     | f       | 0
venueid   | smallint                    | none     | t       | 0
catid     | smallint                    | none     | f       | 0
dateid    | smallint                    | none     | f       | 0
eventname | character varying(200)      | none     | f       | 0
starttime | timestamp without time zone | none     | f       | 0
```

# CREATE TEMPLATE
<a name="r_CREATE_TEMPLATE"></a>

为 Amazon Redshift 命令（例如 [COPY](r_COPY.md)）创建可重用的模板。模板存储可在多个命令执行中引用的常用参数，从而提高一致性并减少手动参数规范。

模板消除了在多个操作中重复指定相同格式化参数的需要，而源路径、目标表和授权可能因操作而异。

## 所需的权限
<a name="r_CREATE_TEMPLATE-privileges"></a>

要创建模板，您必须拥有以下其中一项：
+ 超级用户权限
+ 对要在其中创建模板的架构拥有 CREATE 权限，或者对要在其中创建模板的数据库中的架构拥有 CREATE 限定范围权限

## 语法
<a name="r_CREATE_TEMPLATE-synopsis"></a>

```
CREATE [ OR REPLACE ] TEMPLATE [database_name.][schema_name.]template_name
FOR COPY [ AS ]
[ [ FORMAT ] [ AS ] data_format ]
[ parameter [ argument ] [ , ... ] ];
```

## 参数
<a name="r_CREATE_TEMPLATE-parameters"></a>

 *OR REPLACE*   
如果指定的数据库和架构中已存在同名的模板，则将替换现有模板。您只能将模板替换为定义相同操作类型的新模板，例如 COPY。您必须具有替换模板所需的权限。

*database\$1name*  
（可选）将在其中创建模板的数据库的名称。如果未指定，则在当前数据库中创建模板。  
如果数据库或架构不存在，则不会创建模板，并且语句将返回错误。您无法在系统数据库 `template0`、`template1`、`padb_harvest` 或 `sys:internal` 中创建模板。

*schema\$1name*  
（可选）将在其中创建模板的架构的名称。如果未指定，则在当前架构中创建模板。  
如果提供了架构名称，则在该架构中创建新模板（假定创建者有权访问架构）。模板名称必须是该架构中的唯一名称。

*template\$1name*  
要创建的模板的名称。（可选）可以使用数据库名称和架构名称来限定模板名称。在下面的示例中，`demo_database` 是数据库名称，`demo_schema` 是架构名称，而 `test` 是模板名称。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。  

```
CREATE TEMPLATE demo_database.demo_schema.test FOR COPY AS CSV;
```

COPY  
指定为其创建模板的 Redshift 命令类型。目前仅支持 COPY 命令。

[ [ FORMAT ] [ AS ] *data\$1format* ]   
此参数为可选参数。这指定了 COPY 操作的数据格式。

[ *parameter* [ argument ]]  
指定的 redshift 命令的任何有效参数。  
例如，COPY 命令的模板可能包括：  
+ [数据格式参数](copy-parameters-data-format.md)
+ [文件压缩参数](copy-parameters-file-compression.md)
+ [数据转换参数](copy-parameters-data-conversion.md)
+ [数据加载操作](copy-parameters-data-load.md)
有关支持的参数的完整列表，请参阅 [COPY](r_COPY.md) 命令。

### 使用说明
<a name="create_template-usage-notes"></a>
+ 默认情况下，所有用户都对 PUBLIC schema 具有 CREATE 和 USAGE 权限。要禁止用户在数据库的 PUBLIC schema 中创建对象，请使用 REVOKE 命令删除该权限。
+ 当某个参数同时存在于模板和命令中时，命令参数优先。
+ 模板是数据库对象，并遵循标准的 Redshift 对象命名和权限规则。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。
+ 模板不能包含 [COPY](r_COPY.md) 命令的清单文件规范。

### 限制
<a name="create_template-limitations"></a>
+ 创建模板时，必须指定至少一个参数。
+ 排除的参数：模板中不能包含特定于命令的参数，例如源路径、目标表、授权凭证和清单文件规范。这些参数必须在实际命令中指定。
+ 每个集群的最大模板数量：每个集群最多可以创建 1000 个模板。此限制适用于集群中所有数据库和架构的模板总数。
+ 跨数据库引用：不能跨数据库引用模板。
+ 数据共享：模板不能包含在数据共享中。必须在需要模板的每个集群中单独创建模板。

## 示例
<a name="r_CREATE_TEMPLATE-examples"></a>

以下示例为 COPY 命令创建一个模板 

```
CREATE TEMPLATE test_schema.demo_template
FOR COPY
AS
FORMAT JSON 'auto'
NULL AS ''
MAXERROR 100;
```

使用 [SHOW TEMPLATE](r_SHOW_TEMPLATE.md) 获取模板的定义：

```
SHOW TEMPLATE test_schema.demo_template;
CREATE OR REPLACE TEMPLATE dev.test_schema.demo_template FOR COPY AS FORMAT AS JSON 'auto' NULL '' MAXERROR 100;
```

 查询 [SYS\$1REDSHIFT\$1TEMPLATE](SYS_REDSHIFT_TEMPLATE.md) 系统视图以获取有关模板的更多详细信息。

```
SELECT * FROM SYS_REDSHIFT_TEMPLATE;

database_name | schema_name | template_name | template_type |        create_time         |     last_modified_time     | owner_id | last_modified_by | template_parameters 
---------------+-------------+---------------+---------------+----------------------------+----------------------------+----------+------------------+---------------------
 dev           | test_schema | demo_template |             1 | 2025-12-17 20:06:01.944171 | 2025-12-17 20:06:01.944171 |        1 |                1 | {
    "JSON": "auto",
    "MAXERROR": 100,
    "NULL": ""
}
```

# CREATE USER
<a name="r_CREATE_USER"></a>

创建新的数据库用户。数据库用户可以根据他们的权限和角色，在数据库中检索数据、运行命令和执行其他操作。您必须是数据库超级用户才能执行此命令。

## 所需的权限
<a name="r_CREATE_USER-privileges"></a>

以下是 CREATE USER 所需的权限：
+ Superuser
+ 具有 CREATE USER 权限的用户

## 语法
<a name="r_CREATE_USER-synopsis"></a>

```
CREATE USER name [ WITH ]
PASSWORD { 'password' | 'md5hash' | 'sha256hash' | DISABLE }
[ option [ ... ] ]

where option can be:

CREATEDB | NOCREATEDB
| CREATEUSER | NOCREATEUSER
| SYSLOG ACCESS { RESTRICTED | UNRESTRICTED }
| IN GROUP groupname [, ... ]
| VALID UNTIL 'abstime'
| CONNECTION LIMIT { limit | UNLIMITED }
| SESSION TIMEOUT limit
| EXTERNALID external_id
```

## 参数
<a name="r_CREATE_USER-parameters"></a>

 *name*   
要创建的用户的名称。用户名称不能为 `PUBLIC`。有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。

WITH  
可选关键字。Amazon Redshift 将会忽略 WITH

PASSWORD \$1 '*password*' \$1 '*md5hash*' \$1 '*sha256hash*' \$1 DISABLE \$1  
设置用户的密码。  
默认情况下，用户可以更改自己的密码，除非密码被禁用。要禁用用户的密码，请指定 DISABLE。禁用某个用户的密码后，将从系统中删除该密码，而此用户只能使用临时 AWS Identity and Access Management (IAM) 用户凭证进行登录。有关更多信息，请参阅[使用 IAM 身份验证生成数据库用户凭证](https://docs.aws.amazon.com/redshift/latest/mgmt/generating-user-credentials.html)。只有超级用户才能启用或禁用密码。您不能禁用超级用户的密码。要启用密码，请运行 [ALTER USER](r_ALTER_USER.md) 并指定密码。  
您可采用明文、MD5 哈希字符串或 SHA256 哈希字符串的形式指定密码。  
 使用 AWS 管理控制台、AWS CLI 或 Amazon Redshift API 启动新集群时，必须为初始数据库用户提供一个明文密码。您稍后可以使用 [ALTER USER](r_ALTER_USER.md) 更改密码。
对于明文，密码必须遵循以下约束：  
+ 它的长度必须介于 8 到 64 个字符之间。
+ 它必须包含至少一个大写字母、一个小写字母和一个数字。
+ 它可以使用带有 ASCII 代码 33–126 的任何 ASCII 字符，但 '（单引号）、"（双引号）、\$1、/ 或 @ 除外。
作为以明文形式传递 CREATE USER 密码参数的更安全的替代方法，您可以指定包含密码和用户名的 MD5 哈希。  
当您指定 MD5 哈希字符串时，CREATE USER 命令将检查是否存在有效的 MD5 哈希字符串，但它不会验证字符串的密码部分。在这种情况下，可以创建无法用于登录数据库的密码（如空字符串）。
要指定 MD5 密码，请执行以下步骤：  

1. 联接密码和用户名。

   例如，对于密码 `ez` 和用户 `user1`，联接后的字符串为 `ezuser1`。

1. 将联接后的字符串转换为 32 字符 MD5 哈希字符串。您可以使用任何 MD5 实用工具创建哈希字符串。以下示例使用 Amazon Redshift [MD5 函数](r_MD5.md) 和联接运算符 (\$1\$1) 返回 32 字符的 MD5 哈希字符串。

   ```
   select md5('ez' || 'user1');
                           
   md5
   --------------------------------
   153c434b4b77c89e6b94f12c5393af5b
   ```

1. 在 MD5 哈希字符串前面联接“`md5`”并提供联接后的字符串作为 *md5hash* 参数。

   ```
   create user user1 password 'md5153c434b4b77c89e6b94f12c5393af5b';
   ```

1. 使用登录凭证登录数据库。

   对于此示例，请使用密码 `user1` 以 `ez` 的身份登录。
还有一种安全的替代方法，即指定密码字符串的 SHA-256 哈希值；您也可以提供自己的有效 SHA-256 摘要和用于创建摘要的 256 位加密盐。  
+ 摘要 – 哈希函数的输出。
+ 加密盐 – 随机生成的与密码相结合使用的数据，帮助减少哈希函数输出中的模式。

```
'sha256|Mypassword'
```

```
'sha256|digest|256-bit-salt'
```
在以下示例中，Amazon Redshift 生成并管理加密盐。  

```
CREATE USER admin PASSWORD 'sha256|Mypassword1';
```
在以下示例中，提供了有效的 SHA-256 摘要和用于创建摘要的 256 位加密盐。  
要指定密码并使用您自己的加密盐对其进行哈希处理，请按照以下步骤操作：  

1. 创建 256 位加密盐。您可以通过使用任何十六进制字符串生成器生成长度为 64 个字符的字符串来获取加密盐。在本例中，加密盐为 `c721bff5d9042cf541ff7b9d48fa8a6e545c19a763e3710151f9513038b0f6c6`。

1.  使用 FROM\$1HEX 函数将您的加密盐转换为二进制。这是因为 SHA2 函数需要加密盐的二进制表示。查看以下语句。

   ```
   SELECT FROM_HEX('c721bff5d9042cf541ff7b9d48fa8a6e545c19a763e3710151f9513038b0f6c6');
   ```

1.  使用 CONCAT 函数将加密盐附加到密码。在本示例中，密码为 `Mypassword1`。查看以下语句。

   ```
   SELECT CONCAT('Mypassword1',FROM_HEX('c721bff5d9042cf541ff7b9d48fa8a6e545c19a763e3710151f9513038b0f6c6'));
   ```

1. 使用 SHA2 函数根据您的密码和加密盐组合创建摘要。查看以下语句。

   ```
   SELECT SHA2(CONCAT('Mypassword1',FROM_HEX('c721bff5d9042cf541ff7b9d48fa8a6e545c19a763e3710151f9513038b0f6c6')), 0);
   ```

1.  使用前面步骤中的摘要和加密盐来创建用户。查看以下语句。

   ```
   CREATE USER admin PASSWORD 'sha256|821708135fcc42eb3afda85286dee0ed15c2c461d000291609f77eb113073ec2|c721bff5d9042cf541ff7b9d48fa8a6e545c19a763e3710151f9513038b0f6c6';
   ```

1. 使用登录凭证登录数据库。

    对于此示例，请使用密码 `admin` 以 `Mypassword1` 的身份登录。
如果在未指定哈希函数的情况下设置纯文本形式的密码，则会将用户名用作加密盐生成 MD5 摘要。

CREATEDB \$1 NOCREATEDB   
CREATEDB 选项允许新用户创建数据库。默认值为 NOCREATEDB。

CREATEUSER \$1 NOCREATEUSER   
使用 CREATEUSER 选项可以创建具备所有数据库权限的超级用户，包括 CREATE USER。默认值为 NOCREATEUSER。有关更多信息，请参阅 [超级用户](r_superusers.md)。

SYSLOG ACCESS \$1 RESTRICTED \$1 UNRESTRICTED \$1  <a name="create-user-syslog-access"></a>
一个子句，它指定用户必须对 Amazon Redshift 系统表和视图具有的访问级别。  
拥有 SYSLOG ACCESS RESTRICTED 权限的普通用户在用户可见的系统表和视图中只能查看该用户生成的行。默认值为 RESTRICTED。  
拥有 SYSLOG ACCESS UNRESTRICTED 权限的普通用户可以查看用户可见的系统表和视图中的所有行，包括其他用户生成的行。UNRESTRICTED 不向普通用户授予对超级用户可见的表的访问权限。只有超级用户可以查看超级用户可见的表。  
如果向用户授予对系统表的无限制访问权限，用户便可以看到由其他用户生成的数据。例如，STL\$1QUERY 和 STL\$1QUERYTEXT 包含 INSERT、UPDATE 和 DELETE 语句的完整文本（其中可能包含敏感的用户生成数据）。
SVV\$1TRANSACTIONS 中的所有行都对所有用户可见。  
有关更多信息，请参阅 [系统表和视图中的数据可见性](cm_chap_system-tables.md#c_visibility-of-data)。

IN GROUP *groupname*   
指定用户所属的现有组的名称。可列出多个组名。

VALID UNTIL *abstime*   
VALID UNTIL 选项设置一个绝对时间，用户的密码在该时间后将不再有效。默认情况下，密码没有时间限制。

CONNECTION LIMIT \$1 *limit* \$1 UNLIMITED \$1   
允许用户同时打开的数据库连接的最大数量。此限制不适用于超级用户。使用 UNLIMITED 关键字设置允许的并行连接的最大数量。对每个数据库的连接数量可能也会施加限制。有关更多信息，请参阅 [CREATE DATABASE](r_CREATE_DATABASE.md)。默认为 UNLIMITED。要查看当前连接，请查询 [STV\$1SESSIONS](r_STV_SESSIONS.md) 系统视图。  
如果用户及数据库连接限制均适用，当用户尝试连接时，必须有一个同时低于这两个限制的未使用的连接槽可用。

SESSION TIMEOUT *limit*  
会话保持非活动或空闲状态的最长时间（秒）。范围在 60 秒（1 分钟）到 1,728,000 秒（20 天）之间。如果没有为用户设置会话超时，则应用集群设置。有关更多信息，请参阅《Amazon Redshift 管理指南》**中的 [Amazon Redshift 中的配额和限制](https://docs.aws.amazon.com/redshift/latest/mgmt/amazon-redshift-limits.html)。  
设置会话超时时，它仅应用于新会话。  
要查看有关活动用户会话的信息，包括开始时间、用户名和会话超时，请查询 [STV\$1SESSIONS](r_STV_SESSIONS.md) 系统视图。要查看有关用户会话历史记录的信息，请查询 [STL\$1SESSIONS](r_STL_SESSIONS.md) 视图。要检索有关数据库用户的信息（包括会话超时值），请查询 [SVL\$1USER\$1INFO](r_SVL_USER_INFO.md) 视图。

EXTERNALID *external\$1id*  
用户的标识符，与身份提供者关联。用户必须已禁用密码。有关更多信息，请参阅 [Amazon Redshift 的原生身份提供者 (IdP) 联合身份验证](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-native-idp.html)。

### 使用说明
<a name="create_user-usage-notes"></a>

默认情况下，所有用户都对 PUBLIC schema 具有 CREATE 和 USAGE 权限。要禁止用户在数据库的 PUBLIC schema 中创建对象，请使用 REVOKE 命令删除该权限。

使用 IAM 身份验证创建数据库用户凭证时，您可能希望创建能够仅使用临时凭证登录的超级用户。您不能禁用超级用户的密码，但可以使用随机生成的 MD5 哈希字符串创建一个未知密码。

```
create user iam_superuser password 'md5A1234567890123456780123456789012' createuser;
```

无论 `enable_case_sensitive_identifier` 配置选项的设置如何，系统都会保留双引号括起来的 *username* 的大小写。有关更多信息，请参阅 [enable\$1case\$1sensitive\$1identifier](r_enable_case_sensitive_identifier.md)。

## 示例
<a name="r_CREATE_USER-examples"></a>

以下命令创建一个名为 dbuser 的用户，密码为“abcD1234”，具有数据库创建权限，连接限制为 30。

```
create user dbuser with password 'abcD1234' createdb connection limit 30;
```

 查询 PG\$1USER\$1INFO 目录表，查看有关数据库用户的详细信息。

```
select * from pg_user_info;
         
 usename   | usesysid | usecreatedb | usesuper | usecatupd | passwd   | valuntil | useconfig | useconnlimit
-----------+----------+-------------+----------+-----------+----------+----------+-----------+-------------
 rdsdb     |        1 | true        | true     | true      | ******** | infinity |           |
 adminuser |      100 | true        | true     | false     | ******** |          |           | UNLIMITED
 dbuser    |      102 | true        | false    | false     | ******** |          |           | 30
```

在以下示例中，账户密码在 2017 年 6 月 10 日前有效。

```
create user dbuser with password 'abcD1234' valid until '2017-06-10';
```

 以下示例创建一个具有包含特殊字符的区分大小写的密码的用户。

```
create user newman with password '@AbC4321!';
```

 要在 MD5 密码中使用一个反斜线（“\$1”），请在源字符串中用另一个反斜杠对该反斜杠进行转义。以下示例创建一个名为 `slashpass` 的用户并使用一个反斜杠（“`\`”）作为密码。

```
select md5('\\'||'slashpass');
         
md5
--------------------------------
0c983d1a624280812631c5389e60d48c
```

使用 md5 密码创建用户。

```
create user slashpass password 'md50c983d1a624280812631c5389e60d48c';
```

下面的示例创建了一个名为 `dbuser` 的用户，其空闲会话超时设置为 120 秒。

```
CREATE USER dbuser password 'abcD1234' SESSION TIMEOUT 120;
```

下面的示例创建了一个名为 `bob` 的用户。命名空间为 `myco_aad`。这只是一个示例。要成功运行该命令，您必须具有已注册的身份提供商。有关更多信息，请参阅 [Amazon Redshift 的原生身份提供者 (IdP) 联合身份验证](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-native-idp.html)。

```
CREATE USER myco_aad:bob EXTERNALID "ABC123" PASSWORD DISABLE;
```

# CREATE VIEW
<a name="r_CREATE_VIEW"></a>

在数据库中创建一个视图。视图实际上不是具体化的；每当查询中引用视图时，系统都会运行定义视图的查询。要使用外部表创建视图，请包括 WITH NO SCHEMA BINDING 子句。

要创建标准视图，您需要对基础表或基础视图的访问权限。要查询标准视图，您需要选择针对视图本身的权限，但不需要选择针对基础表的权限。如果您创建的视图引用了其他架构中的表或视图，或者创建的视图引用了实体化视图，则需要使用权限。要查询后期绑定视图，您需要选择针对后期绑定视图本身的权限。您还应该确定后期绑定视图的所有者具有对引用的对象（表、视图或用户定义的函数）的选择权限。有关后期绑定视图的更多信息，请参阅[使用说明](#r_CREATE_VIEW_usage_notes)。

## 所需的权限
<a name="r_CREATE_VIEW-privileges"></a>

要使用 CREATE VIEW，需要以下权限之一。
+ 要使用 CREATE [ OR REPLACE ] VIEW 创建视图，请执行以下操作：
  + Superuser
  + 具有 CREATE [ REPLACE ] VIEW 权限的用户
+ 要使用 CREATE OR REPLACE VIEW 替换现有视图，请执行以下操作：
  + Superuser
  + 具有 CREATE [ OR REPLACE ] VIEW 权限的用户
  + 视图拥有者

如果用户想要访问包含用户定义函数的视图，则用户必须具有该函数的 EXECUTE 权限。

## 语法
<a name="r_CREATE_VIEW-synopsis"></a>

```
CREATE [ OR REPLACE ] VIEW name [ ( column_name [, ...] ) ] AS query
[ WITH NO SCHEMA BINDING ]
```

## 参数
<a name="r_CREATE_VIEW-parameters"></a>

OR REPLACE   
如果存在同名视图，则将替换视图。您只能将视图替换为生成相同的列集的新查询（使用相同的列名和数据类型）。CREATE OR REPLACE VIEW 将锁定视图以阻止读取和写入，直至操作完成。  
替换视图时，将保留它的其他属性（如所有权和授予的权限）。

 *名称*   
视图的名称。如果提供 schema 名称（例如，`myschema.myview`），则使用指定 schema 创建视图。否则，将在当前 schema 中创建视图。视图名称必须与同一 schema 中任何其他视图或表的名称不同。  
如果指定以“\$1”开头的视图名称，则视图创建为仅在当前会话中可见的临时视图。  
有关有效名称的更多信息，请参阅[名称和标识符](r_names.md)。您无法在系统数据库 template0、template1、padb\$1harvest 或 sys:internal 中创建表或视图。

 *column\$1name*   
要用于视图中的列的名称的可选列表。如果未提供列名，则从查询派生列名。可在单个视图中定义的列的最大数目为 1,600。

 *query*   
计算结果为表的查询（采用 SELECT 语句的形式）。此表定义视图中的列和行。

 WITH NO SCHEMA BINDING   
指定视图未绑定到基础数据库对象（例如表和用户定义的函数）的子句。因此，视图与其引用的对象之间不存在依赖关系。即使引用的对象不存在，您也可以创建视图。由于不存在依赖关系，删除或更改引用的对象不会影响视图。在查询视图之前，Amazon Redshift 不会检查依赖关系。后期绑定视图不支持递归公用表表达式（rCTE）。要查看有关后期绑定视图的详细信息，请运行 [PG\$1GET\$1LATE\$1BINDING\$1VIEW\$1COLS](PG_GET_LATE_BINDING_VIEW_COLS.md) 函数。  
在包括 WITH NO SCHEMA BINDING 子句时，必须使用 schema 名称来限定 SELECT 语句中引用的表和视图。创建视图时，即使引用的表不存在，schema 也必须存在。例如，以下语句将返回错误。  

```
create view myevent as select eventname from event
with no schema binding;
```
以下语句将成功运行。  

```
create view myevent as select eventname from public.event
with no schema binding;
```

**注意**  
无法从视图进行更新、插入或删除操作。

## 使用说明
<a name="r_CREATE_VIEW_usage_notes"></a>



### 后期绑定视图
<a name="r_CREATE_VIEW_late-binding-views"></a>

后期绑定视图不检查基础数据库对象（如表和视图），直至该视图被查询为止。因此，您可以修改或删除基础对象，而不必删除和重新创建视图。如果您删除了基础对象，对后期绑定视图的查询将失败。如果对后期绑定视图的查询引用了基础对象中不存在的列，查询将失败。

 如果您删除然后重新创建了后期绑定视图的基础表或视图，将使用默认访问权限创建新对象。您可能需要为将查询视图的用户授予对基础对象的权限。

要创建后期绑定视图，请加入 WITH NO SCHEMA BINDING 子句。以下示例创建一个没有 schema 绑定的视图。

```
create view event_vw as select * from public.event
with no schema binding;
```

```
select * from event_vw limit 1;
            
eventid | venueid | catid | dateid | eventname     | starttime
--------+---------+-------+--------+---------------+--------------------
      2 |     306 |     8 |   2114 | Boris Godunov | 2008-10-15 20:00:00
```

以下示例显示您可以修改基础表，而不必重新创建视图。

```
alter table event rename column eventname to title;
```

```
select * from event_vw limit 1;
            
eventid | venueid | catid | dateid | title         | starttime
--------+---------+-------+--------+---------------+--------------------
      2 |     306 |     8 |   2114 | Boris Godunov | 2008-10-15 20:00:00
```

您只能在后期绑定视图中引用 Amazon Redshift Spectrum 外部表。后期绑定视图的一种应用是查询 Amazon Redshift和 Redshift Spectrum 表。例如，您可以使用 [UNLOAD](r_UNLOAD.md) 命令将较旧的数据归档至 Amazon S3 。然后，创建一个 Redshift Spectrum 外部表，该表引用 Amazon S3 中的数据并创建一个可查询这两个表的视图。以下示例使用 UNION ALL 子句来联接 Amazon Redshift `SALES` 表和 Redshift Spectrum `SPECTRUM.SALES` 表。

```
create view sales_vw as
select * from public.sales
union all
select * from spectrum.sales
with no schema binding;
```

有关创建 Redshift Spectrum 外部表（包括 `SPECTRUM.SALES` 表）的更多信息，请参阅[Amazon Redshift Spectrum 入门](c-getting-started-using-spectrum.md)。

**重要**  
从后期绑定视图创建标准视图时，标准视图的定义包含创建标准视图时后期绑定视图的定义，包括后期绑定视图的拥有者。如果您在底层的后期绑定视图中进行了更改，则在重新创建标准视图之前，这些更改不会在标准视图中使用。因此，当查询标准视图时，它将始终使用后期绑定视图的定义和后期绑定视图的拥有者在创建标准视图时进行权限检查。

要更新标准视图以引用后期绑定视图的最新定义，请使用创建标准视图时使用的初始视图定义运行 CREATE OR REPLACE VIEW。

请参阅以下示例，了解如何从后期绑定视图中创建标准视图。

```
create view sales_vw_lbv as 
select * from public.sales 
with no schema binding;

show view sales_vw_lbv;
                            Show View DDL statement
--------------------------------------------------------------------------------
 create view sales_vw_lbv as select * from public.sales with no schema binding;
(1 row)

create view sales_vw as 
select * from sales_vw_lbv;

show view sales_vw;
                                               Show View DDL statement
---------------------------------------------------------------------------------------------------------------------
 SELECT sales_vw_lbv.price, sales_vw_lbv."region" FROM (SELECT sales.price, sales."region" FROM sales) sales_vw_lbv;
(1 row)
```

请注意，标准视图的 DDL 语句中所示的后期绑定视图是在创建标准视图时定义的，并且不会随着您之后对后期绑定视图所做的任何更改而更新。

## 示例
<a name="r_CREATE_VIEW-examples"></a>

示例命令使用一组名为 *TICKIT* 数据库的对象和数据示例。有关更多信息，请参阅[示例数据库](https://docs.aws.amazon.com/redshift/latest/dg/c_sampledb.html)。

以下命令从名为 EVENT 的表创建一个名为 *myevent* 的视图。

```
create view myevent as select eventname from event
where eventname = 'LeAnn Rimes';
```

以下命令从名为 USERS 的表创建一个名为* myuser* 的视图。

```
create view myuser as select lastname from users;
```

以下命令从名为 USERS 的表创建或替换一个名为* myuser* 的视图。

```
create or replace view myuser as select lastname from users;
```

以下示例创建一个没有 schema 绑定的视图。

```
create view myevent as select eventname from public.event
with no schema binding;
```

# DEALLOCATE
<a name="r_DEALLOCATE"></a>

取消分配预编译语句。

## 语法
<a name="r_DEALLOCATE-synopsis"></a>

```
DEALLOCATE [PREPARE] plan_name
```

## 参数
<a name="r_DEALLOCATE-parameters"></a>

PREPARE   
此关键字是可选的，并且将被忽略。

 *plan\$1name*   
要取消分配的预编译语句的名称。

## 使用说明
<a name="r_DEALLOCATE_usage_notes"></a>

DEALLOCATE 用于取消分配先前准备好的 SQL 语句。如果您未明确取消分配预编译语句，则将在当前会话结束时取消分配该语句。有关预编译语句的更多信息，请参阅[PREPARE](r_PREPARE.md)。

## 另请参阅
<a name="r_DEALLOCATE-see-also"></a>

 [EXECUTE](r_EXECUTE.md), [PREPARE](r_PREPARE.md) 

# DECLARE
<a name="declare"></a>

定义新游标。使用游标从大型查询的结果集中一次性检索几个行。

在提取游标的第一行时，会在领导节点上、内存中或磁盘上具体化整个结果集（如果需要）。由于将游标用于大型结果集可能会降低性能，因此建议使用备用方法（如果可能）。有关更多信息，请参阅 [使用游标时的性能注意事项](#declare-performance)。

您必须在事务块中声明游标。对于每个会话，一次只能打开一个游标。

有关更多信息，请参阅[FETCH](fetch.md)、[CLOSE](close.md)。

## 语法
<a name="declare-synopsis"></a>

```
DECLARE cursor_name CURSOR FOR query
```

## 参数
<a name="declare-parameters"></a>

*cursor\$1name*   
新游标的名称。

 *query*   
填充游标的 SELECT 语句。

## DECLARE CURSOR 使用说明
<a name="declare-usage"></a>

如果您的客户端应用程序使用 ODBC 连接，并且您的查询创建的结果集太大，无法存储到内存中，则可使用光标将结果集流式传输到客户端应用程序。在使用游标时，会在领导节点上具体化整个结果集，随后您的客户端可按递增方式提取结果。

**注意**  
若要在 ODBC 中为 Microsoft Windows 启用游标，请在您用于 Amazon Redshift 的 ODBC DSN 中启用**使用声明/取回**选项。建议使用 ODBC DSN 选项对话框中的 **Cache Size** 字段将多节点集群中的 ODBC 缓存大小设置为 4,000 或更大值，以最大程度地减少往返操作。在单节点集群上，将缓存大小设置为 1000。

由于使用游标可能会对性能产生负面影响，我们建议您尽可能地使用替代方法。有关更多信息，请参阅 [使用游标时的性能注意事项](#declare-performance)。

支持 Amazon Redshift 游标，但存在以下限制：
+ 对于每个会话，一次只能打开一个游标。
+ 游标必须在事务内部使用 (BEGIN … END)。
+ 所有游标的累计最大结果集大小受到集群节点类型的限制。如果您需要更大的结果集，可以调整为 XL 和 8XL 节点配置。

  有关更多信息，请参阅 [游标约束](#declare-constraints)。

## 游标约束
<a name="declare-constraints"></a>

在提取游标的第一行时，会在领导节点上具体化整个结果集。如果结果集无法存储到内存中，则会根据需要写入磁盘。为了保护领导节点的完整性，Amazon Redshift 会根据集群节点类型对所有游标结果集的大小强制实施约束。

下表显示每个集群节点类型的最大结果集总大小。最大结果集大小以 MB 为单位。


| 节点类型 | 每个集群的最大结果集大小 (MB) | 
| --- | --- | 
|   DC2 Large 多节点   | 192000 | 
|   DC2 Large 单节点   | 8000 | 
|   DC2 8XL 多节点   | 3200000 | 
|   RA3 16XL 多个节点   | 14400000 | 
|   RA3 4XL 多个节点   | 3200000 | 
|   RA3 XLPLUS 多节点   | 1000000 | 
|   RA3 XLPLUS 单节点   | 64000 | 
|   RA3 LARGE 多节点   | 240000 | 
|   RA3 LARGE 单节点   | 8000 | 
| Amazon Redshift Serverless | 150000 | 

要查看某个集群的活动游标配置，请以超级用户身份查询 [STV\$1CURSOR\$1CONFIGURATION](r_STV_CURSOR_CONFIGURATION.md) 系统表。要查看活动光标的状态，请查询 [STV\$1ACTIVE\$1CURSORS](r_STV_ACTIVE_CURSORS.md) 系统表。用户只能看到自己游标所对应的行，而超级用户可以查看所有游标。

## 使用游标时的性能注意事项
<a name="declare-performance"></a>

由于在开始将结果返回给客户端之前，游标会在领导节点上具体化整个结果集，因此对超大型结果集使用游标时，会对性能产生负面影响。我们强烈建议不要对超大型结果集使用游标。在一些情况下，例如您的应用程序使用 ODBC 连接时，游标可能是唯一可行的解决方案。我们建议尽可能地利用下面这些备选方案：
+ 使用 [UNLOAD](r_UNLOAD.md) 导出大型表。在使用 UNLOAD 时，计算节点将并行工作，从而将数据直接发送到 Amazon Simple Storage Service 上的数据文件。有关更多信息，请参阅 [在 Amazon Redshift 中卸载数据](c_unloading_data.md)。
+ 在您的客户端应用程序中设置 JDBC 提取大小参数。如果您使用 JDBC 连接，并且遇到客户端内存不足错误，则可以通过设置 JDBC 提取大小参数，让您的客户端按较小的批次检索结果集。有关更多信息，请参阅 [设置 JDBC 提取大小参数](set-the-JDBC-fetch-size-parameter.md)。

## DECLARE CURSOR 示例
<a name="declare-example"></a>

以下示例声明一个名为 LOLLAPALOOZA 的游标，以便为 Lollapalooza 事件选择销售信息，然后使用该游标从结果集中提取行：

```
-- Begin a transaction

begin;

-- Declare a cursor

declare lollapalooza cursor for
select eventname, starttime, pricepaid/qtysold as costperticket, qtysold
from sales, event
where sales.eventid = event.eventid
and eventname='Lollapalooza';

-- Fetch the first 5 rows in the cursor lollapalooza:

fetch forward 5 from lollapalooza;

  eventname   |      starttime      | costperticket | qtysold
--------------+---------------------+---------------+---------
 Lollapalooza | 2008-05-01 19:00:00 |   92.00000000 |       3
 Lollapalooza | 2008-11-15 15:00:00 |  222.00000000 |       2
 Lollapalooza | 2008-04-17 15:00:00 |  239.00000000 |       3
 Lollapalooza | 2008-04-17 15:00:00 |  239.00000000 |       4
 Lollapalooza | 2008-04-17 15:00:00 |  239.00000000 |       1
(5 rows)

-- Fetch the next row:

fetch next from lollapalooza;

  eventname   |      starttime      | costperticket | qtysold
--------------+---------------------+---------------+---------
 Lollapalooza | 2008-10-06 14:00:00 |  114.00000000 |       2

-- Close the cursor and end the transaction:

close lollapalooza;
commit;
```

以下示例使用表中的所有结果遍历 refcursor：

```
CREATE TABLE tbl_1 (a int, b int);
INSERT INTO tbl_1 values (1, 2),(3, 4);

CREATE OR REPLACE PROCEDURE sp_cursor_loop() AS $$
DECLARE
    target record;
    curs1 cursor for select * from tbl_1;
BEGIN
    OPEN curs1;
    LOOP
        fetch curs1 into target;
        exit when not found;
        RAISE INFO 'a %', target.a;
    END LOOP;
    CLOSE curs1;
END;
$$ LANGUAGE plpgsql;

CALL sp_cursor_loop();
         
SELECT message 
   from svl_stored_proc_messages 
   where querytxt like 'CALL sp_cursor_loop()%';
         
  message
----------
      a 1
      a 3
```

# DELETE
<a name="r_DELETE"></a>

从表中删除行。

**注意**  
单个 SQL 语句的最大大小为 16MB。

## 语法
<a name="r_DELETE-synopsis"></a>

```
[ WITH [RECURSIVE] common_table_expression [, common_table_expression , ...] ]
DELETE [ FROM ] { table_name | materialized_view_name }
    [ { USING } table_name, ... ]
    [ WHERE condition ]
```

## 参数
<a name="r_DELETE-parameters"></a>

WITH 子句  
可选子句，指定一个或多个 *common-table-expressions*。请参阅 [WITH 子句](r_WITH_clause.md)。

FROM  
FROM 关键字是可选的，不过在指定 USING 子句时除外。语句 `delete from event;` 和 `delete event;` 执行相同的操作，可从 EVENT 表中删除所有行。  
要从表中删除所有行，请对表执行 [TRUNCATE](r_TRUNCATE.md)。TRUNCATE 的效率要比 DELETE 高很多，不需要 VACUUM 和 ANALYZE。不过请注意，TRUNCATE 在其运行的事务中提交事务。

 *table\$1name*   
一个临时或永久表。只有表的所有者或对表具有 DELETE 权限的用户才能从表中删除行。  
考虑对大型表使用 TRUNCATE 命令来快速执行非限定的删除操作；请参阅 [TRUNCATE](r_TRUNCATE.md)。  
在从表中删除大量行之后：  
+ 对表执行 Vacuum 操作，以回收存储空间并对行重新排序。
+ 分析表以更新查询计划程序的统计数据。

 *materialized\$1view\$1name*   
实体化视图。DELETE 语句适用于用于[流式摄取到实体化视图](materialized-view-streaming-ingestion.md)的实体化视图。只有实体化视图的所有者或对实体化视图具有 DELETE 权限的用户才能从中删除行。  
如果行级别安全性 (RLS) 策略未向用户授予 IGNORE RLS 权限，则您无法在用于流式摄取的实体化视图上运行 DELETE。但有一个例外：如果向执行 DELETE 操作的用户授予了 IGNORE RLS，则此操作会成功运行。有关更多信息，请参阅 [RLS 策略拥有权和管理](https://docs.aws.amazon.com/redshift/latest/dg/t_rls_ownership.html)。

USING *table\$1name*, ...  
在 WHERE 子句条件中引用附加表时，使用 USING 关键字可以引入表列表。例如，以下语句从 EVENT 表中删除满足 EVENT 和 SALES 表上的联接条件的所有行。必须在 FROM 列表中明确指定 SALES 表：  

```
delete from event using sales where event.eventid=sales.eventid;
```
如果您在 USING 子句中重复目标表名称，DELETE 操作将运行自联接。您可以在 WHERE 子句中使用子查询，以取代 USING 语法来编写相同的查询。

WHERE *condition*   
一个限制只删除那些符合条件的行的可选子句。例如，条件可以是对列的限制，也可以是联接条件或基于查询结果的条件。查询可以引用 DELETE 命令的目标以外的其他表。例如：  

```
delete from t1
where col1 in(select col2 from t2);
```
如果未指定条件，将删除表中的所有行。

## 使用说明
<a name="r_DELETE-usage"></a>
+ DELETE 操作在连接到以下任何一项的 Amazon Redshift 流式传输实体化视图上运行时，将持有排他锁：
  +  Amazon Kinesis 数据流 
  +  Amazon Managed Streaming for Apache Kafka 主题 
  +  支持的外部流，例如 Confluent Cloud Kafka 主题 

  有关更多信息，请参阅 [流式摄取到实体化视图](materialized-view-streaming-ingestion.md)。

## 示例
<a name="r_DELETE-examples"></a>

从 CATEGORY 表中删除所有行：

```
delete from category;
```

从 CATEGORY 表中删除 CATID 值在 0 与 9 之间的行：

```
delete from category
where catid between 0 and 9;
```

从 LISTING 表中删除其 SELLERID 值在 SALES 表中不存在的行：

```
delete from listing
where listing.sellerid not in(select sales.sellerid from sales);
```

以下两个查询均根据与 EVENT 表的联接以及 CATID 列的额外限制，从 CATEGORY 表中删除一行：

```
delete from category
using event
where event.catid=category.catid and category.catid=9;
```

```
delete from category
where catid in
(select category.catid from category, event
where category.catid=event.catid and category.catid=9);
```

以下查询从 `mv_cities` 实体化视图中删除所有行。此示例中的实体化视图名称是一个示例：

```
delete from mv_cities;
```

# DESC DATASHARE
<a name="r_DESC_DATASHARE"></a>

显示使用 ALTER DATASHARE 添加到数据共享的数据库对象的列表。Amazon Redshift 显示表、视图和函数的名称、数据库、schema 和类型。

使用系统视图可以找到有关数据共享对象的其他信息。有关更多信息，请参阅 [SVV\$1DATASHARE\$1OBJECTS](https://docs.aws.amazon.com/redshift/latest/dg/r_SVV_DATASHARE_OBJECTS.html) 和 [SVV\$1DATASHARES](https://docs.aws.amazon.com/redshift/latest/dg/r_SVV_DATASHARES.html)。

## 语法
<a name="r_DESC_DATASHARE-synopsis"></a>

```
DESC DATASHARE datashare_name [ OF [ ACCOUNT account_id ] NAMESPACE namespace_guid ]
```

## 参数
<a name="r_DESC_DATASHARE-parameters"></a>

 *datashare\$1name*   
数据共享的名称。

NAMESPACE *namespace\$1guid*   
指定数据共享使用的命名空间的值。当您以使用者集群管理员身份运行 DESC DATAHSARE 时，请指定 NAMESPACE 参数以查看入站数据共享。

ACCOUNT *account\$1id*  
它指定数据共享所属的账户的值。

## 使用说明
<a name="r_DESC_DATASHARE-usage"></a>

作为使用者账户管理员，当您运行 DESC DATASHARE 以查看 AWS 账户内的入站数据共享时，请指定 NAMESPACE 选项。当您运行 DESC DATASHARE 以查看跨 AWS 账户的入站数据共享时，请指定 ACCOUNT 和 NAMESPACE 选项。

## 示例
<a name="r_DESC_DATASHARE-examples"></a>

以下示例显示生产者集群上出站数据共享的信息。

```
DESC DATASHARE salesshare;

producer_account |          producer_namespace           | share_type  | share_name   | object_type |        object_name           |  include_new
-----------------+---------------------------------------+-------------+--------------+-------------+------------------------------+--------------
 123456789012    | 13b8833d-17c6-4f16-8fe4-1a018f5ed00d  | OUTBOUND    |  salesshare  | TABLE       | public.tickit_sales_redshift |
 123456789012    | 13b8833d-17c6-4f16-8fe4-1a018f5ed00d  | OUTBOUND    |  salesshare  | SCHEMA      | public                       |   t
```

以下示例显示使用者集群上入站数据共享的信息。

```
DESC DATASHARE salesshare of ACCOUNT '123456789012' NAMESPACE '13b8833d-17c6-4f16-8fe4-1a018f5ed00d';

 producer_account |          producer_namespace          | share_type | share_name | object_type |         object_name          |  include_new
------------------+--------------------------------------+------------+------------+-------------+------------------------------+--------------
 123456789012     | 13b8833d-17c6-4f16-8fe4-1a018f5ed00d | INBOUND    | salesshare | table       | public.tickit_sales_redshift |
 123456789012     | 13b8833d-17c6-4f16-8fe4-1a018f5ed00d | INBOUND    | salesshare | schema      | public                       |
(2 rows)
```

# DESC IDENTITY PROVIDER
<a name="r_DESC_IDENTITY_PROVIDER"></a>

显示有关身份提供者的信息。只有超级用户可以描述身份提供者。

## 语法
<a name="r_DESC_IDENTITY_PROVIDER-synopsis"></a>

```
DESC IDENTITY PROVIDER identity_provider_name
```

## 参数
<a name="r_DESC_IDENTITY_PROVIDER-parameters"></a>

 *identity\$1provider\$1name*   
身份提供者的名称。

## 示例
<a name="r_DESC_IDENTITY_PROVIDER-examples"></a>

以下示例显示有关您的身份提供者的信息。

```
DESC IDENTITY PROVIDER azure_idp;
```

示例输出。

```
  uid   |   name    | type  |              instanceid              | namespc |                                                                                                                                                 params                                                                                                                                                  | enabled
--------+-----------+-------+--------------------------------------+---------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------
 126692 | azure_idp | azure | e40d4bb2-7670-44ae-bfb8-5db013221d73 | aad     | {"issuer":"https://login.microsoftonline.com/e40d4bb2-7670-44ae-bfb8-5db013221d73/v2.0", "client_id":"871c010f-5e61-4fb1-83ac-98610a7e9110", "client_secret":'', "audience":["https://analysis.windows.net/powerbi/connector/AmazonRedshift", "https://analysis.windows.net/powerbi/connector/AWSRDS"]} | t
(1 row)
```

# DETACH MASKING POLICY
<a name="r_DETACH_MASKING_POLICY"></a>

将已附加的动态数据掩蔽策略与列分离。有关动态数据掩蔽的更多信息，请参阅 [动态数据掩蔽](t_ddm.md)。

超级用户和具有 sys:secadmin 角色的用户或角色可以分离策略。

## 语法
<a name="r_DETACH_MASKING_POLICY-synopsis"></a>

```
DETACH MASKING POLICY
{
  policy_name ON table_name
  | database_name.policy_name ON database_name.schema_name.table_name
}
( output_column_names )
FROM { user_name | ROLE role_name | PUBLIC };
```

## 参数
<a name="r_DETACH_MASKING_POLICY-parameters"></a>

 *policy\$1name*   
要分离的屏蔽策略的名称。

database\$1name  
在其中创建策略和关系的数据库的名称。策略和关系必须在同一个数据库中。该数据库可以是连接的数据库，也可以是支持 Amazon Redshift 联合身份验证权限的数据库。

schema\$1name  
关系所属的架构的名称。

 *table\$1name*   
要从中分离屏蔽策略的表的名称。

*output\$1column\$1names*   
附加了屏蔽策略的列的名称。

*user\$1name*   
附加了屏蔽策略的用户的名称。  
在单个 DETACH MASKING POLICY 语句中，您只能设置 user\$1name、role\$1name 和 PUBLIC 中的一项。

*role\$1name*   
附加了屏蔽策略的角色的名称。  
在单个 DETACH MASKING POLICY 语句中，您只能设置 user\$1name、role\$1name 和 PUBLIC 中的一项。

*PUBLIC*   
显示策略已附加到表中的所有用户。  
在单个 DETACH MASKING POLICY 语句中，您只能设置 user\$1name、role\$1name 和 PUBLIC 中的一项。

有关在 Amazon Redshift 联合身份验证权限目录上使用 DETACH MASKING POLICY 的信息，请参阅[使用 Amazon Redshift 联合身份验证权限管理访问控制](https://docs.aws.amazon.com/redshift/latest/dg/federated-permissions-managing-access.html)。

# DETACH RLS POLICY
<a name="r_DETACH_RLS_POLICY"></a>

将表上的行级别安全性策略与一个或多个用户或角色分离。

超级用户和具有 `sys:secadmin` 角色的用户或角色可以分离策略。

## 语法
<a name="r_DETACH_RLS_POLICY-synopsis"></a>

```
DETACH RLS POLICY
{
  policy_name ON [TABLE] table_name [, ...]
  | database_name.policy_name ON [TABLE] database_name.schema_name.table_name [, ...]
}
FROM { user_name | ROLE role_name | PUBLIC } [, ...];
```

## 参数
<a name="r_DETACH_RLS_POLICY-parameters"></a>

 *policy\$1name*   
策略的名称。

database\$1name  
在其中创建策略和关系的数据库的名称。策略和关系必须在同一个数据库中。该数据库可以是连接的数据库，也可以是支持 Amazon Redshift 联合身份验证权限的数据库。

schema\$1name  
关系所属的架构的名称。

table\$1name  
行级安全策略所附加到的关系。

FROM \$1 *user\$1name* \$1 ROLE *role\$1name* \$1 PUBLIC\$1 [, ...]  
指定策略是否与一个或多个指定的用户或角色分离。

有关在 Amazon Redshift 联合身份验证权限目录上使用 DETACH RLS POLICY 的信息，请参阅[使用 Amazon Redshift 联合身份验证权限管理访问控制](https://docs.aws.amazon.com/redshift/latest/dg/federated-permissions-managing-access.html)。

## 使用说明
<a name="r_DETACH_RLS_POLICY-usage"></a>

在使用 DETACH RLS POLICY 语句时，请遵守以下规则：
+ 您可以将策略与关系、用户、角色或公共分离。

## 示例
<a name="r_DETACH_RLS_POLICY-examples"></a>

以下示例将表上的策略与角色分离。

```
DETACH RLS POLICY policy_concerts ON tickit_category_redshift FROM ROLE analyst, ROLE dbadmin;
```

# DROP DATABASE
<a name="r_DROP_DATABASE"></a>

删除数据库。

您不能在以下事务块中运行 DROP DATABASE：(BEGIN ... END)。有关事务的更多信息，请参阅 [Amazon Redshift 中的隔离级别](c_serial_isolation.md)。

## 语法
<a name="r_DROP_DATABASE-synopsis"></a>

```
DROP DATABASE database_name [ FORCE ]
```

## 参数
<a name="r_DROP_DATABASE-parameters"></a>

 *database\$1name*   
要删除的数据库的名称。您不能删除 dev、padb\$1harvest、template0、template1 或 sys:internal 数据库，并且不能删除当前数据库。  
要删除外部数据库，请删除外部架构。有关更多信息，请参阅 [DROP SCHEMA](r_DROP_SCHEMA.md)。

 FORCE   
指定了 FORCE 时，DROP DATABASE 会在删除数据库之前尝试终止活动连接。如果在超时时间内成功终止了所有活动连接，则继续执行删除操作。如果未能终止所有连接，则命令将引发错误。

## DROP DATABASE 使用说明
<a name="r_DROP_DATABASE_usage"></a>

使用 DROP DATABASE 语句时，请注意以下事项：
+ 通常，我们不建议您使用 DROP DATABASE 语句删除包含 AWS Data Exchange 数据共享的数据库。如果您这样做的话，有权访问数据共享的 AWS 账户 将失去访问权限。执行这种类型的更改可能会违反 AWS Data Exchange 中的数据产品条款。

  以下示例显示了删除包含 AWS Data Exchange 数据共享的数据库会出现的错误。

  ```
  DROP DATABASE test_db;
  ERROR:   Drop of database test_db that contains ADX-managed datashare(s) requires session variable datashare_break_glass_session_var to be set to value 'ce8d280c10ad41'
  ```

  要允许删除数据库，请设置以下变量，然后再次运行 DROP DATABASE 语句。

  ```
  SET datashare_break_glass_session_var to 'ce8d280c10ad41';
  ```

  ```
  DROP DATABASE test_db;
  ```

  在这种情况下，Amazon Redshift 会生成一个随机的一次性值来设置会话变量，以允许对包含 AWS Data Exchange 数据共享的数据库执行 DROP DATABASE。

## 示例
<a name="r_DROP_DATABASE-examples"></a>

以下示例删除名为 TICKIT\$1TEST 的数据库：

```
drop database tickit_test;
```

# DROP DATASHARE
<a name="r_DROP_DATASHARE"></a>

删除数据共享。此命令无法撤消。

只有超级用户或数据共享拥有者才可以删除数据共享。

## 所需的权限
<a name="r_DROP_DATASHARE-privileges"></a>

以下是 DROP DATASHARE 所需的权限：
+ Superuser
+ 具有 DROP DATASHARE 权限的用户
+ 数据共享拥有者

## 语法
<a name="r_DROP_DATASHARE-synopsis"></a>

```
DROP DATASHARE datashare_name;
```

## 参数
<a name="r_DROP_DATASHARE-parameters"></a>

 *datashare\$1name*   
要删除的数据共享的名称。

## DROP DATASHARE 使用说明
<a name="r_DROP_DATASHARE_usage"></a>

使用 DROP DATASHARE 语句时，请注意以下事项：
+ 通常，我们不建议您使用 DROP DATASHARE 语句删除 AWS Data Exchange 数据共享。如果您这样做的话，有权访问数据共享的 AWS 账户 将失去访问权限。执行这种类型的更改可能会违反 AWS Data Exchange 中的数据产品条款。

  以下示例显示了删除 AWS Data Exchange 数据共享时会出现的错误。

  ```
  DROP DATASHARE salesshare;
  ERROR:  Drop of ADX-managed datashare salesshare requires session variable datashare_break_glass_session_var to be set to value '620c871f890c49'
  ```

  要允许删除 AWS Data Exchange 数据共享，请设置以下变量，然后再次运行 DROP DATASHARE 语句。

  ```
  SET datashare_break_glass_session_var to '620c871f890c49';
  ```

  ```
  DROP DATASHARE salesshare;
  ```

  在这种情况下，Amazon Redshift 会生成一个随机的一次性值来设置会话变量，以允许对 AWS Data Exchange 数据共享执行 DROP DATASHARE。

## 示例
<a name="r_DROP_DATASHARE-examples"></a>

以下示例将删除名为 `salesshare` 的数据共享。

```
DROP DATASHARE salesshare;
```

# DROP EXTERNAL VIEW
<a name="r_DROP_EXTERNAL_VIEW"></a>

从数据库中删除外部视图。删除外部视图会将其从与该视图关联的所有 SQL 引擎（例如 Amazon Athena 和 Amazon EMR Spark）中删除。此命令无法逆转。有关 Data Catalog 视图的更多信息，请参阅 [AWS Glue Data Catalog 视图](https://docs.aws.amazon.com/redshift/latest/dg/data-catalog-views-overview.html)。

## 语法
<a name="r_DROP_EXTERNAL_VIEW-synopsis"></a>

```
DROP EXTERNAL VIEW schema_name.view_name [ IF EXISTS ]
{catalog_name.schema_name.view_name | awsdatacatalog.dbname.view_name | external_schema_name.view_name}
```

## 参数
<a name="r_DROP_EXTERNAL_VIEW-parameters"></a>

 *schema\$1name.view\$1name*   
附加到 AWS Glue 数据库的架构，后面是视图的名称。

IF EXISTS  
仅当视图存在时才会将其删除。

catalog\$1name.schema\$1name.view\$1name \$1 awsdatacatalog.dbname.view\$1name \$1 external\$1schema\$1name.view\$1name  
删除视图时要使用的架构符号。可以指定使用您创建的 Glue 数据库 AWS Glue Data Catalog 或您创建的外部架构。有关更多信息，请参阅 [CREATE DATABASE](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_DATABASE.html) 和 [CREATE EXTERNAL SCHEMA](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_SCHEMA.html)。

 *query\$1definition*   
Amazon Redshift 为更改视图而运行的 SQL 查询的定义。

## 示例
<a name="r_DROP_EXTERNAL_VIEW-examples"></a>

以下示例删除了一个名为 sample\$1schema.glue\$1data\$1catalog\$1view 的 Data Catalog 视图。

```
DROP EXTERNAL VIEW sample_schema.glue_data_catalog_view IF EXISTS
```

# DROP FUNCTION
<a name="r_DROP_FUNCTION"></a>

从数据库中删除用户定义的函数 (UDF)。由于可能存在名称相同但签名不同的多个函数，因此必须指定函数签名或参数数据类型列表。不能删除 Amazon Redshift 内置函数。

此命令无法撤消。

## 所需的权限
<a name="r_DROP_FUNCTION-privileges"></a>

以下是 DROP FUNCTION 所需的权限：
+ Superuser
+ 具有 DROP FUNCTION 权限的用户
+ 函数拥有者

## 语法
<a name="r_DROP_FUNCTION-synopsis"></a>

```
DROP FUNCTION name
( [arg_name] arg_type   [, ...] )
[ CASCADE | RESTRICT ]
```

## 参数
<a name="r_DROP_FUNCTION-parameters"></a>

 *name*   
要删除的函数的名称。

 *arg\$1name*   
输入参数的名称。由于在确定函数身份时只需要参数数据类型，因此 DROP FUNCTION 会忽略参数名称。

 *arg\$1type*   
输入参数的数据类型。您可以通过逗号分隔的列表形式最多提供 32 个数据类型。

 CASCADE   
一个关键字，用于自动删除依赖于该函数的对象，例如视图。  
要创建不依赖于函数的视图，请在定义视图时包括 WITH NO SCHEMA BINDING 子句。有关更多信息，请参阅 [CREATE VIEW](r_CREATE_VIEW.md)。

 RESTRICT   
一个关键字，用于指定如果有任何对象依赖于该函数，则不删除函数并返回一条消息。此操作是默认操作。

## 示例
<a name="r_DROP_FUNCTION-examples"></a>

以下示例删除名为 `f_sqrt` 的函数：

```
drop function f_sqrt(int);
```

要删除具有依赖项的函数，请使用 CASCADE 选项，如以下示例所示：

```
drop function f_sqrt(int)cascade;
```

# DROP GROUP
<a name="r_DROP_GROUP"></a>

删除用户组。此命令无法撤消。此命令不删除组中的单个用户。

要删除单个用户，请参阅 DROP USER。

## 语法
<a name="r_DROP_GROUP-synopsis"></a>

```
DROP GROUP name
```

## 参数
<a name="r_DROP_GROUP-parameter"></a>

 *名称*   
要删除的用户组的名称。

## 示例
<a name="r_DROP_GROUP-example"></a>

以下示例删除 `guests` 用户组：

```
DROP GROUP guests;
```

如果组具有对象的任何权限，则不能删除组。如果您尝试删除这样的组，将收到以下错误。

```
ERROR: group "guests" can't be dropped because the group has a privilege on some object
```

如果组具有对象的权限，则必须撤消权限，然后再删除组。要查找 `guests` 组有权访问的对象，请使用以下示例。有关示例中使用的元数据视图的更多信息，请参阅 [SVV\$1RELATION\$1PRIVILEGES](https://docs.aws.amazon.com//redshift/latest/dg/r_SVV_RELATION_PRIVILEGES.html)。

```
SELECT DISTINCT namespace_name, relation_name, identity_name, identity_type 
FROM svv_relation_privileges
WHERE identity_type='group' AND identity_name='guests';

+----------------+---------------+---------------+---------------+
| namespace_name | relation_name | identity_name | identity_type |
+----------------+---------------+---------------+---------------+
| public         | table1        | guests        | group         |
+----------------+---------------+---------------+---------------+
| public         | table2        | guests        | group         |
+----------------+---------------+---------------+---------------+
```

以下示例从 `guests` 用户组撤消对 `public` schema 中的所有表的所有权限，然后删除该组。

```
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM GROUP guests;
DROP GROUP guests;
```

# DROP IDENTITY PROVIDER
<a name="r_DROP_IDENTITY_PROVIDER"></a>

删除身份提供者。此命令无法撤消。只有超级用户可以删除身份提供者。

## 语法
<a name="r_DROP_IDENTITY_PROVIDER-synopsis"></a>

```
DROP IDENTITY PROVIDER identity_provider_name [ CASCADE ]
```

## 参数
<a name="r_DROP_IDENTITY_PROVIDER-parameter"></a>

 *identity\$1provider\$1name*   
要删除的身份提供者的名称。

 CASCADE   
删除身份提供者时，会删除附加到身份提供者的用户和角色。

## 示例
<a name="r_DROP_IDENTITY_PROVIDER-example"></a>

以下示例删除 *oauth\$1provider* 身份提供者。

```
DROP IDENTITY PROVIDER oauth_provider;
```

如果删除身份提供者，某些用户可能无法登录或无法使用配置为使用身份提供者的客户端工具。

# DROP LIBRARY
<a name="r_DROP_LIBRARY"></a>

从数据库中删除自定义 Python 库。只有库所有者或超级用户可以删除库。

DROP LIBRARY 无法在事务块 (BEGIN … END) 中运行。有关事务的更多信息，请参阅 [Amazon Redshift 中的隔离级别](c_serial_isolation.md)。

此命令无法撤消。DROP LIBRARY 命令将立即提交。如果依赖于所删除库的 UDF 正在并行运行，UDF 可能失败，即使 UDF 正在事务中运行也是如此。

有关更多信息，请参阅 [CREATE LIBRARY](r_CREATE_LIBRARY.md)。

## 所需的权限
<a name="r_DROP_LIBRARY-privileges"></a>

以下是 DROP LIBRARY 所需的权限：
+ Superuser
+ 具有 DROP LIBRARY 权限的用户
+ 库拥有者

## 语法
<a name="r_DROP_LIBRARY-synopsis"></a>

```
DROP LIBRARY library_name
```

## 参数
<a name="r_DROP_LIBRARY-parameters"></a>

 *library\$1name*   
库的名称。

# DROP MASKING POLICY
<a name="r_DROP_MASKING_POLICY"></a>

从所有数据库中删除动态数据掩蔽策略。您无法删除仍然附加到一个或多个表的屏蔽策略。有关动态数据掩蔽的更多信息，请参阅 [动态数据掩蔽](t_ddm.md)。

超级用户和具有 sys:secadmin 角色的用户或角色可以删除屏蔽策略。

## 语法
<a name="r_DROP_MASKING_POLICY-synopsis"></a>

```
DROP MASKING POLICY { policy_name | database_name.policy_name };
```

## 参数
<a name="r_DROP_MASKING_POLICY-parameters"></a>

 *policy\$1name*   
要删除的屏蔽策略的名称。

database\$1name  
从其中生成策略的数据库的名称。该数据库可以是连接的数据库，也可以是支持 Amazon Redshift 联合身份验证权限的数据库。

有关在 Amazon Redshift 联合身份验证权限目录上使用 DROP MASKING POLICY 的信息，请参阅[使用 Amazon Redshift 联合身份验证权限管理访问控制](https://docs.aws.amazon.com/redshift/latest/dg/federated-permissions-managing-access.html)。

# DROP MODEL
<a name="r_DROP_MODEL"></a>

从数据库中删除模型。只有模型拥有者或超级用户才可以删除模型。

DROP MODEL 还会删除从此模型派生的所有相关预测函数、与模型相关的所有 Amazon Redshift 构建以及与模型相关的所有 Amazon S3 数据。当模型仍在 Amazon SageMaker AI 中进行训练时，DROP MODEL 将取消这些操作。

此命令无法撤消。DROP MODEL 命令将立即提交。

## 所需的权限
<a name="r_DROP_MODEL-privileges"></a>

以下是 DROP MODEL 所需的权限：
+ Superuser
+ 具有 DROP MODEL 权限的用户
+ 模型拥有者
+ Schema 拥有者

## 语法
<a name="r_DROP_MODEL-synopsis"></a>

```
DROP MODEL [ IF EXISTS ] model_name
```

## 参数
<a name="r_DROP_MODEL-parameters"></a>

 *IF EXISTS*   
一个子句，指示如果指定 schema 已存在，则此命令不应进行任何更改，并应返回一条指示 schema 存在的消息。

 *model\$1name*   
模型的名称。schema 中的模型名称必须是唯一的。

## 示例
<a name="r_DROP_MODEL-examples"></a>

以下示例删除模型 demo\$1ml.customer\$1churn。

```
DROP MODEL demo_ml.customer_churn
```

# DROP MATERIALIZED VIEW
<a name="materialized-view-drop-sql-command"></a>

删除实体化视图。

有关实体化视图的更多信息，请参阅[Amazon Redshift 中的实体化视图](materialized-view-overview.md)。

## 语法
<a name="mv_DROP_MATERIALIZED_VIEW-synopsis"></a>

```
DROP MATERIALIZED VIEW [ IF EXISTS ] mv_name [, ... ] [ CASCADE | RESTRICT ]
```

## 参数
<a name="mv_DROP_MATERIALIZED_VIEW-parameters"></a>

IF EXISTS  
一个子句，旨在检查指定的实体化视图是否存在。如果实体化视图不存在，则 `DROP MATERIALIZED VIEW` 命令会返回一条错误消息。此子句在编写脚本时非常有用，可以防止在删除不存在的实体化视图时出现脚本失败的情况。

*mv\$1name*  
要删除的实体化视图的名称。

CASCADE  
一个子句，用于指示自动删除实体化视图所依赖的对象，例如其他视图。

RESTRICT  
一个子句，用于指示如果有任何对象依赖该实体化视图，则不删除该视图。这是默认值。

## 使用说明
<a name="mv_DROP_MATERIALIZED_VIEW-usage"></a>

仅实体化视图的拥有者才能对该视图使用 `DROP MATERIALIZED VIEW`。超级用户或被特别授予 DROP 权限的用户可以是例外。

当您为实体化视图编写 drop 语句并且存在具有匹配名称的视图时，会导致错误，指示您使用 DROP VIEW。即使在您使用 `DROP MATERIALIZED VIEW IF EXISTS` 的情况下也会发生这一错误。

## 示例
<a name="mv_DROP_MATERIALIZED_VIEW-examples"></a>

以下示例删除 `tickets_mv` 实体化视图。

```
DROP MATERIALIZED VIEW tickets_mv;
```

# DROP PROCEDURE
<a name="r_DROP_PROCEDURE"></a>

删除过程。要删除过程，需要提供过程名称和输入参数数据类型（签名）。（可选）您可以包含完整的参数数据类型，包括 OUT 参数。要查找过程的签名，请使用 [SHOW PROCEDURE](r_SHOW_PROCEDURE.md) 命令。有关过程签名的更多信息，请参阅[PG\$1PROC\$1INFO](r_PG_PROC_INFO.md)。

## 所需的权限
<a name="r_DROP_PROCEDURE-privileges"></a>

以下是 DROP PROCEDURE 所需的权限：
+ Superuser
+ 具有 DROP PROCEDURE 权限的用户
+ 过程拥有者

## 语法
<a name="r_DROP_PROCEDURE-synopsis"></a>

```
DROP PROCEDURE sp_name ( [ [ argname ] [ argmode ] argtype [, ...] ] )
```

## 参数
<a name="r_DROP_PROCEDURE-parameters"></a>

 *sp\$1name*   
要删除的过程的名称。

 *argname*   
输入参数的名称。由于在确定过程身份时只需要参数数据类型，因此 DROP PROCEDURE 会忽略参数名称。

 *argmode*   
参数的模式，可以是 IN、OUT 或 INOUT。OUT 参数是可选的，因为它们不用于标识存储过程。

 *argtype*   
输入参数的数据类型。有关支持的数据类型的列表，请参阅[数据类型](c_Supported_data_types.md)。

## 示例
<a name="r_DROP_PROCEDURE-examples"></a>

以下示例删除名为 `quarterly_revenue` 的存储过程。

```
DROP PROCEDURE quarterly_revenue(volume INOUT bigint, at_price IN numeric,result OUT int);
```

# DROP RLS POLICY
<a name="r_DROP_RLS_POLICY"></a>

删除所有数据库中所有表的行级别安全性策略。

超级用户和具有 sys:secadmin 角色的用户或角色可以删除策略。

## 语法
<a name="r_DROP_RLS_POLICY-synopsis"></a>

```
DROP RLS POLICY [ IF EXISTS ] 
{ policy_name | database_name.policy_name }
[ CASCADE | RESTRICT ]
```

## 参数
<a name="r_DROP_RLS_POLICY-parameters"></a>

 *IF EXISTS*   
指示指定策略是否已存在的子句。

 *policy\$1name*   
策略的名称。

database\$1name  
从其中生成策略的数据库的名称。该数据库可以是连接的数据库，也可以是支持 Amazon Redshift 联合身份验证权限的数据库。

 *CASCADE*   
一个子句，用于指示在删除策略之前自动将策略与所有附加的表分离。

 *RESTRICT*   
一个子句，用于指示在将策略附加到某些表时不删除策略。这是默认值。

有关在 Amazon Redshift 联合身份验证权限目录上使用 DROP RLS POLICY 的信息，请参阅[使用 Amazon Redshift 联合身份验证权限管理访问控制](https://docs.aws.amazon.com/redshift/latest/dg/federated-permissions-managing-access.html)。

## 示例
<a name="r_DROP_RLS_POLICY-examples"></a>

以下示例删除了行级别安全性策略。

```
DROP RLS POLICY policy_concerts;
```

# DROP ROLE
<a name="r_DROP_ROLE"></a>

从数据库中删除角色。只有创建角色的角色拥有者、使用 WITH ADMIN 选项的用户或超级用户才能删除角色。

您不能删除已授予用户的角色或依赖此角色的其他角色。

## 所需的权限
<a name="r_DROP_ROLE-privileges"></a>

以下是 DROP ROLE 所需的权限：
+ Superuser
+ 角色拥有者，是创建角色的用户，或者是已被授予具有 WITH ADMIN OPTION 权限的角色的用户。

## 语法
<a name="r_DROP_ROLE-synopsis"></a>

```
DROP ROLE role_name [ FORCE | RESTRICT ] 
```

## 参数
<a name="r_DROP_ROLE-parameters"></a>

*role\$1name*  
角色的名称。

[ FORCE \$1 RESTRICT ]  
默认设置为 RESTRICT。当您尝试删除继承了其他角色的角色时，Amazon Redshift 会返回错误。使用 FORCE 删除所有角色分配（如果存在）。

## 示例
<a name="r_DROP_ROLE-examples"></a>

下面的示例将删除角色 `sample_role`。

```
DROP ROLE sample_role FORCE;
```

下面的示例尝试使用默认 RESTRICT 选项删除授予用户的角色 sample\$1role1。

```
CREATE ROLE sample_role1;
GRANT ROLE sample_role1 TO user1;
DROP ROLE sample_role1;
ERROR:  cannot drop this role since it has been granted on a user
```

要成功删除已授予用户的 sample\$1role1，请使用 FORCE 选项。

```
DROP ROLE sample_role1 FORCE;
```

下面的示例尝试使用默认 RESTRICT 选项删除另一个角色依赖的角色 sample\$1role2。

```
CREATE ROLE sample_role1;
CREATE ROLE sample_role2;
GRANT ROLE sample_role1 TO sample_role2;
DROP ROLE sample_role2;
ERROR:  cannot drop this role since it depends on another role
```

要成功删除被另一个角色依赖的 sample\$1role2，请使用 FORCE 选项。

```
DROP ROLE sample_role2 FORCE;
```

# DROP SCHEMA
<a name="r_DROP_SCHEMA"></a>

删除 schema。对于外部架构，您还可以删除与该架构关联的外部数据库。此命令无法撤消。

## 所需的权限
<a name="r_DROP_SCHEMA-privileges"></a>

以下是 DROP SCHEMA 所需的权限：
+ Superuser
+ Schema 拥有者
+ 具有 DROP SCHEMA 权限的用户

## 语法
<a name="r_DROP_SCHEMA-synopsis"></a>

```
DROP SCHEMA [ IF EXISTS ] name [, ...]
[ DROP EXTERNAL DATABASE ]
[ CASCADE | RESTRICT ]
```

## 参数
<a name="r_DROP_SCHEMA-parameters"></a>

IF EXISTS  
一个子句，指示如果指定的 schema 不存在，则命令不应进行任何更改，并返回一条指示 schema 不存在的消息，而不是以错误终止。  
此子句在编写脚本时很有用，可使在 DROP SCHEMA 针对不存在的 schema 运行时脚本不会失败。

 *名称*   
要删除的架构的名称。您可以指定以逗号分隔的多个架构名称。

 DROP EXTERNAL DATABASE   
这个子句指示，如果删除外部架构，则删除与它关联的外部数据库（如果存在）。如果不存在外部数据库，则该命令将返回一条消息，说明不存在外部数据库。如果删除多个外部架构，则删除与指定架构关联的所有数据库。  
如果外部数据库包含从属对象（如表），则还应包括 CASCADE 选项以删除从属对象。  
删除外部数据库时，还会删除与该数据库关联的任何其他外部架构的数据库。使用该数据库的其他外部架构中定义的表也将被删除。  
DROP EXTERNAL DATABASE 不支持存储在 HIVE 元存储中的外部数据库。

CASCADE  
一个关键字，指示自动删除架构中所有对象。如果指定了 DROP EXTERNAL DATABASE，则还会删除外部数据库中的所有对象。

RESTRICT  
一个关键字，指示如果架构中包含任何对象，则不删除该架构或外部数据库。此操作是默认操作。

## 示例
<a name="r_DROP_SCHEMA-example"></a>

以下示例删除名为 S\$1SALES 的架构。本示例使用 RESTRICT 作为安全机制，以便在 schema 包含对象的情况下不会将其删除。在这种情况下，您需要先删除架构对象，然后再删除架构。

```
drop schema s_sales restrict;
```

以下示例删除名为 S\$1SALES 的架构以及依赖该架构的所有对象。

```
drop schema s_sales cascade;
```

以下示例删除 S\$1SALES schema（如果存在）；如果不存在该 schema，则不执行任何操作并返回一条消息。

```
drop schema if exists s_sales;
```

以下示例删除名为 S\$1SPECTRUM 的外部架构以及与之关联的外部数据库。此示例使用 RESTRICT，以便在架构和数据库包含任何对象时不会将其删除。在这种情况下，您需要先删除从属对象，然后再删除架构和数据库。

```
drop schema s_spectrum drop external database restrict;
```

以下示例删除多个架构、与之关联的外部数据库以及任何从属对象。

```
drop schema s_sales, s_profit, s_revenue drop external database cascade;
```

# DROP TABLE
<a name="r_DROP_TABLE"></a>

从数据库中删除表。

如果您正在尝试清空表中的行，而不是删除表，请使用 DELETE 或 TRUNCATE 命令。

DROP TABLE 删除目标表上存在的约束。可以使用一条 DROP TABLE 命令删除多个表。

针对外部表的 DROP TABLE 不能在事务 (BEGIN … END) 内运行。有关事务的更多信息，请参阅 [Amazon Redshift 中的隔离级别](c_serial_isolation.md)。

要查找向组授予 DROP 特权的示例，请参阅 GRANT [示例](r_GRANT-examples.md)。

## 所需的权限
<a name="r_DROP_TABLE-privileges"></a>

以下是 DROP TABLE 所需的权限：
+ Superuser
+ 具有 DROP TABLE 权限的用户
+ 对模式拥有 USAGE 权限的表拥有者

## 语法
<a name="r_DROP_TABLE-synopsis"></a>

```
DROP TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
```

## 参数
<a name="r_DROP_TABLE-parameters"></a>

IF EXISTS  
一个子句，指示如果指定的表不存在，则命令不应进行任何更改，并返回一条指示表不存在的消息，而不是以错误终止。  
此子句在编写脚本时很有用，可使在 DROP TABLE 针对不存在的表运行时脚本不会失败。

 *名称*   
要删除的表的名称。

CASCADE  
一个子句，用于指示自动删除依赖该表的对象，例如视图。  
要使创建的视图不依赖于其他数据库对象（例如视图和表），请在定义视图时包括 WITH NO SCHEMA BINDING 子句。有关更多信息，请参阅 [CREATE VIEW](r_CREATE_VIEW.md)。

RESTRICT   
一个子句，指示如果任何对象依赖该表，则不删除该表。此操作是默认操作。

## 示例
<a name="r_DROP_TABLE-examples"></a>

 **删除没有依赖项的表** 

以下示例创建一个名为 FEEDBACK 且没有依赖项的表，然后删除该表：

```
create table feedback(a int);

drop table feedback;
```

 如果表包含由视图或其他表引用的列，Amazon Redshift 将显示一条消息，如下所示。

```
Invalid operation: cannot drop table feedback because other objects depend on it
```

 **同时删除两个表** 

以下命令集创建一个 FEEDBACK 表和一个 BUYERS 表，然后在一条命令中同时删除这两个表：

```
create table feedback(a int);

create table buyers(a int);

drop table feedback, buyers;
```

 **删除具有依赖项的表** 

以下步骤说明如何使用 CASCADE 开关删除名为 FEEDBACK 的表。

首先，使用 CREATE TABLE 命令创建一个名为 FEEDBACK 的简单表：

```
create table feedback(a int);
```

 下一步，使用 CREATE VIEW 命令创建一个名为 FEEDBACK\$1VIEW 的视图，并使该视图依赖于 FEEDBACK 表：

```
create view feedback_view as select * from feedback;
```

 以下示例删除 FEEDBACK 表，同时会删除 FEEDBACK\$1VIEW 视图，因为 FEEDBACK\$1VIEW 视图依赖于 FEEDBACK 表：

```
drop table feedback cascade;
```

 **查看表的依赖项** 

要返回表的依赖关系，请使用以下示例。用您自己的架构和表替换 *my\$1schema* 和 *my\$1table*。

```
SELECT dependent_ns.nspname as dependent_schema
, dependent_view.relname as dependent_view 
, source_ns.nspname as source_schema
, source_table.relname as source_table
, pg_attribute.attname as column_name
FROM pg_depend 
JOIN pg_rewrite ON pg_depend.objid = pg_rewrite.oid 
JOIN pg_class as dependent_view ON pg_rewrite.ev_class = dependent_view.oid 
JOIN pg_class as source_table ON pg_depend.refobjid = source_table.oid 
JOIN pg_attribute ON pg_depend.refobjid = pg_attribute.attrelid 
    AND pg_depend.refobjsubid = pg_attribute.attnum 
JOIN pg_namespace dependent_ns ON dependent_ns.oid = dependent_view.relnamespace
JOIN pg_namespace source_ns ON source_ns.oid = source_table.relnamespace
WHERE 
source_ns.nspname = 'my_schema'
AND source_table.relname = 'my_table'
AND pg_attribute.attnum > 0 
ORDER BY 1,2
LIMIT 10;
```

要删除 *my\$1table* 及其依赖关系，请使用以下示例。此示例还返回已删除的表的所有依赖关系。

```
DROP TABLE my_table CASCADE;
         
SELECT dependent_ns.nspname as dependent_schema
, dependent_view.relname as dependent_view 
, source_ns.nspname as source_schema
, source_table.relname as source_table
, pg_attribute.attname as column_name
FROM pg_depend 
JOIN pg_rewrite ON pg_depend.objid = pg_rewrite.oid 
JOIN pg_class as dependent_view ON pg_rewrite.ev_class = dependent_view.oid 
JOIN pg_class as source_table ON pg_depend.refobjid = source_table.oid 
JOIN pg_attribute ON pg_depend.refobjid = pg_attribute.attrelid 
    AND pg_depend.refobjsubid = pg_attribute.attnum 
JOIN pg_namespace dependent_ns ON dependent_ns.oid = dependent_view.relnamespace
JOIN pg_namespace source_ns ON source_ns.oid = source_table.relnamespace
WHERE 
source_ns.nspname = 'my_schema'
AND source_table.relname = 'my_table'
AND pg_attribute.attnum > 0 
ORDER BY 1,2
LIMIT 10;

+------------------+----------------+---------------+--------------+-------------+
| dependent_schema | dependent_view | source_schema | source_table | column_name |
+------------------+----------------+---------------+--------------+-------------+
```

 **使用 IF EXISTS 删除表** 

以下示例删除 FEEDBACK 表（如果存在）；如果不存在该表，则不执行任何操作并返回一条消息：

```
drop table if exists feedback;
```

# DROP TEMPLATE
<a name="r_DROP_TEMPLATE"></a>

从数据库中删除模板。

## 所需的权限
<a name="r_DROP_TEMPLATE-privileges"></a>

要删除模板，您必须拥有以下其中一项：
+ 超级用户权限
+ 对包含模板的架构拥有 DROP TEMPLATE 权限和 USAGE 权限

## 语法
<a name="r_DROP_TEMPLATE-synopsis"></a>

```
DROP TEMPLATE [database_name.][schema_name.]template_name;
```

## 参数
<a name="r_DROP_TEMPLATE-parameters"></a>

 *database\$1name*   
（可选）在其中创建模板的数据库的名称。如果未指定，则使用当前数据库。

 *schema\$1name*   
（可选）在其中创建模板的架构的名称。如果未指定，则在当前搜索路径中搜索模板。

 *template\$1name*   
要移除的模板的名称。在下面的示例中，`demo_database` 是数据库名称，`demo_schema` 是架构名称，而 `test` 是模板名称。  

```
DROP TEMPLATE demo_database.demo_schema.test;
```

## 示例
<a name="r_DROP_TEMPLATE-examples"></a>

以下示例从当前架构中删除模板 test\$1template：

```
DROP TEMPLATE test_template;
```

以下示例从架构 test\$1schema 中删除模板 test\$1template：

```
DROP TEMPLATE test_schema.test_template;
```

# DROP USER
<a name="r_DROP_USER"></a>

从数据库中删除用户。可以使用一条 DROP USER 命令删除多个用户。您必须是数据库超级用户或具有 DROP USER 权限才能运行此命令。

## 语法
<a name="r_DROP_USER-synopsis"></a>

```
DROP USER [ IF EXISTS ] name [, ... ]
```

## 参数
<a name="r_DROP_USER-parameters"></a>

IF EXISTS  
一个子句，指示如果指定的用户不存在，则命令不应进行任何更改，并返回一条指示用户不存在的消息，而不是终止并显示错误。  
此子句在编写脚本时很有用，可使在 DROP USER 针对不存在的用户运行时脚本不会失败。

 *name*   
要删除的用户的名称。您可以使用逗号来分隔各个用户名，从而指定多个用户。

## 使用说明
<a name="r_DROP_USER-notes"></a>

您无法删除名为 `rdsdb` 的用户或数据库的管理员用户（通常名为 `awsuser` 或 `admin`）。

如果用户拥有任何数据库对象（例如架构、数据库、表或视图），或者用户具有对数据库、表、列或组的任何权限，则您不能删除该用户。如果您试图删除此类用户，则会收到以下错误之一。

```
ERROR: user "username" can't be dropped because the user owns some object [SQL State=55006]

ERROR: user "username" can't be dropped because the user has a privilege on some object [SQL State=55006]
```

有关如何查找数据库用户拥有的对象的详细说明，请参阅《知识中心》**中的[如何解决 Amazon Redshift 中的“无法删除用户”错误？](https://repost.aws/knowledge-center/redshift-user-cannot-be-dropped)。

**注意**  
Amazon Redshift 在删除用户前只检查当前数据库。如果用户拥有数据库对象或者对另一数据库中的对象具有任何权限，DROP USER 不会返回错误。如果您删除的用户拥有另一个数据库中的对象，这些对象的所有者将更改为“未知”。

如果用户拥有对象，请先删除对象或者将其所有权更改为其他用户，然后再删除原始用户。如果用户具有对象的权限，请先撤消权限，然后再删除用户。以下示例说明先删除对象、更改所有权、撤消权限然后再删除用户的过程。

```
drop database dwdatabase;
alter schema dw owner to dwadmin;
revoke all on table dwtable from dwuser;
drop user dwuser;
```

## 示例
<a name="r_DROP_USER-examples"></a>

以下示例删除名为 paulo 的用户：

```
drop user paulo;
```

以下示例删除两个用户，即 paulo 和 martha：

```
drop user paulo, martha;
```

在以下示例中，如果用户 paulo 存在，则删除该用户；如果不存在，则不执行任何操作并返回一条消息：

```
drop user if exists paulo;
```

# DROP VIEW
<a name="r_DROP_VIEW"></a>

从数据库中删除视图。可以使用一条 DROP VIEW 命令删除多个视图。此命令无法撤消。

## 所需的权限
<a name="r_DROP_VIEW-privileges"></a>

以下是 DROP VIEW 所需的权限：
+ Superuser
+ 具有 DROP VIEW 权限的用户
+ 视图拥有者

## 语法
<a name="r_DROP_VIEW-synopsis"></a>

```
DROP VIEW [ IF EXISTS ] name [, ... ] [ CASCADE | RESTRICT ] 
```

## 参数
<a name="r_DROP_VIEW-parameters"></a>

IF EXISTS  
一个子句，指示如果指定的视图不存在，则命令不应进行任何更改，并返回一条指示视图不存在的消息，而不是以错误终止。  
此子句在编写脚本时很有用，可使在 DROP VIEW 针对不存在的视图运行时脚本不会失败。

 *名称*   
要删除的视图的名称。

CASCADE  
一个子句，用于指示自动删除依赖该视图的对象，例如其他视图。  
要使创建的视图不依赖于其他数据库对象（例如视图和表），请在定义视图时包括 WITH NO SCHEMA BINDING 子句。有关更多信息，请参阅 [CREATE VIEW](r_CREATE_VIEW.md)。  
请注意，如果您包含 CASCADE 参数并且删除的数据库对象数不少于十个，则数据库客户端可能不会在摘要结果中列出所有已删除的对象。这通常是因为 SQL 客户端工具对返回的结果数有默认限制。

RESTRICT  
一个子句，指示如果任何对象依赖该视图，则不删除该视图。此操作是默认操作。

## 示例
<a name="r_DROP_VIEW-examples"></a>

以下示例删除名为 *event* 的视图：

```
drop view event;
```

要删除具有依赖项的视图，请使用 CASCADE 选项。例如，假如我们从名为 EVENT 的表开始。接下来，我们使用 CREATE VIEW 命令创建 EVENT 表的 eventview 视图，如以下示例所示：

```
create view eventview as
select dateid, eventname, catid
from event where catid = 1;
```

现在，我们创建另一个名为 *myeventview* 的视图，该视图基于第一个视图 *eventview*：

```
create view myeventview as
select eventname, catid
from eventview where eventname <> ' ';
```

此时创建了两个视图：*eventview* 和 *myeventview*。

*myeventview* 视图是以 *eventview* 为父视图的子视图。

要删除 *eventview* 视图，要使用的命令如下：

```
drop view eventview;
```

请注意，如果您在这种情况下运行此命令，会收到以下错误：

```
drop view eventview;
ERROR: can't drop view eventview because other objects depend on it
HINT: Use DROP ... CASCADE to drop the dependent objects too.
```

要对此进行补救，请执行以下命令（按照错误消息中的建议）：

```
drop view eventview cascade;
```

现在，已成功删除 *eventview* 和 *myeventview*。

以下示例删除 *eventview* 视图（如果存在）；如果不存在该视图，则不执行任何操作并返回一条消息：

```
drop view if exists eventview;
```

# END
<a name="r_END"></a>

提交当前事务。执行与 COMMIT 命令完全相同的功能。

有关更详细的文档，请参阅 [COMMIT](r_COMMIT.md)。

## 语法
<a name="r_END-synopsis"></a>

```
END [ WORK | TRANSACTION ]
```

## 参数
<a name="r_END-parameters"></a>

WORK  
可选关键字。

TRANSACTION  
可选关键字；WORK 和 TRANSACTION 同义。

## 示例
<a name="r_END-examples"></a>

下面的示例都结束事务块并提交事务：

```
end;
```

```
end work;
```

```
end transaction;
```

在执行以下任一命令后，Amazon Redshift 将结束事务数据块并执行提交。

# EXECUTE
<a name="r_EXECUTE"></a>

执行先前预编译的语句。

## 语法
<a name="r_EXECUTE-synopsis"></a>

```
EXECUTE plan_name [ (parameter [, ...]) ]
```

## 参数
<a name="r_EXECUTE-parameters"></a>

 *plan\$1name*   
要运行的预编译语句的名称。

 *parameter*   
预编译语句的某个参数的实际值。它必须是一个生成某个类型的值的表达式，而且该类型必须与在创建该预编译语句的 PREPARE 命令中为此参数位置指定的数据类型兼容。

## 使用说明
<a name="r_EXECUTE_usage_notes"></a>

EXECUTE 用于执行先前预编译的语句。由于预编译语句只在会话持续时间内存在，因此预编译语句必须已由先前在当前会话中执行的 PREPARE 语句创建。

如果先前的 PREPARE 语句指定了一些参数，则必须将兼容的参数集传递到 EXECUTE 语句，否则 Amazon Redshift 返回错误。与函数不同的是，预编译语句不会根据指定参数的类型或数量来重载；预编译语句的名称在一个数据库会话内必须是唯一的。

为预编译语句发出 EXECUTE 命令时，Amazon Redshift 可能会选择修改查询执行计划（以便根据指定的参数值来提高性能），然后再执行预编译语句。此外，对于预编译语句的每次新执行，Amazon Redshift 可能会根据使用 EXECUTE 语句指定的其他参数值，再次修改查询执行计划。要查看 Amazon Redshift 为任何给定 EXECUTE 语句选择的查询执行计划，请使用 [EXPLAIN](r_EXPLAIN.md) 命令。

有关创建和使用预编译语句的示例和更多信息，请参阅 [PREPARE](r_PREPARE.md)。

## 另请参阅
<a name="r_EXECUTE-see-also"></a>

 [DEALLOCATE](r_DEALLOCATE.md), [PREPARE](r_PREPARE.md) 

# EXPLAIN
<a name="r_EXPLAIN"></a>

显示查询语句的执行计划，而不运行查询。有关查询分析工作流程的信息，请参阅[查询分析工作流程](c-query-analysis-process.md)。

## 语法
<a name="r_EXPLAIN-synopsis"></a>

```
EXPLAIN [ VERBOSE ] query
```

## 参数
<a name="r_EXPLAIN-parameters"></a>

VERBOSE   
显示完整的查询计划，而不只是摘要。

 *query*   
要解释的查询语句。查询可以是 SELECT、INSERT、CREATE TABLE AS、UPDATE 或 DELETE 语句。

## 使用说明
<a name="r_EXPLAIN-usage-notes"></a>

在创建临时表时需要花费一定的时间，因此 EXPLAIN 性能有时会受到影响。例如，使用公共子表达式优化的查询需要创建和分析临时表，以返回 EXPLAIN 输出。查询计划依赖于临时表的 schema 和统计数据。因此，此类查询的 EXPLAIN 命令的运行时间可能会超过预期。

您只能对以下命令使用 EXPLAIN：
+ SELECT
+ SELECT INTO
+ CREATE TABLE AS
+ INSERT
+ UPDATE
+ DELETE

如果您对其他 SQL 命令（例如数据定义语言 (DDL) 或数据库操作）使用 EXPLAIN 命令，则该命令将失败。

Amazon Redshift 使用 EXPLAIN 输出相对单位成本来选择查询计划。Amazon Redshift 会比较各种资源估算值的大小来确定计划。

## 查询计划和执行步骤
<a name="r_EXPLAIN-query-planning-and-execution-steps"></a>

特定 Amazon Redshift 查询语句的执行计划会将查询的执行和计算细分为一系列单独的步骤和表操作，它们最后为该查询生成一个最终结果集。有关查询计划的信息，请参阅[查询处理](c-query-processing.md)。

下表提供了步骤的汇总，Amazon Redshift 可以针对用户提交供执行的任何查询，使用这些步骤来制定执行计划。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_EXPLAIN.html)

## 将 EXPLAIN 用于 RLS
<a name="r_EXPLAIN-RLS"></a>

如果查询包含受行级别安全性 (RLS) 策略约束的表，则 EXPLAIN 将显示一个特殊的 RLS SecureScan 节点。Amazon Redshift 还会将相同的节点类型记录到 STL\$1EXPLAIN 系统表中。EXPLAIN 不会显示应用于 dim\$1tbl 的 RLS 谓词。RLS SecureScan 节点类型用作执行计划包含当前用户不可见的其他操作的指示器。

以下示例说明了 RLS SecureScan 节点。

```
EXPLAIN
SELECT D.cint
FROM fact_tbl F INNER JOIN dim_tbl D ON F.k_dim = D.k
WHERE F.k_dim / 10 > 0;
                               QUERY PLAN
------------------------------------------------------------------------
 XN Hash Join DS_DIST_ALL_NONE  (cost=0.08..0.25 rows=1 width=4)
   Hash Cond: ("outer".k_dim = "inner"."k")
   ->  *XN* *RLS SecureScan f  (cost=0.00..0.14 rows=2 width=4)*
         Filter: ((k_dim / 10) > 0)
   ->  XN Hash  (cost=0.07..0.07 rows=2 width=8)
         ->  XN Seq Scan on dim_tbl d  (cost=0.00..0.07 rows=2 width=8)
               Filter: (("k" / 10) > 0)
```

为了能够对受 RLS 约束的查询计划进行全面调查，Amazon Redshift 提供了 EXPLAIN RLS 系统权限。被授予此权限的用户可以检查还包含 RLS 谓词的完整查询计划。

以下示例说明了 RLS SecureScan 节点下方的额外顺序扫描，该顺序扫描还包括 RLS 策略谓词 (k\$1dim > 1)。

```
EXPLAIN SELECT D.cint
FROM fact_tbl F INNER JOIN dim_tbl D ON F.k_dim = D.k
WHERE F.k_dim / 10 > 0;
                                   QUERY PLAN
---------------------------------------------------------------------------------
 XN Hash Join DS_DIST_ALL_NONE  (cost=0.08..0.25 rows=1 width=4)
   Hash Cond: ("outer".k_dim = "inner"."k")
   *->  XN RLS SecureScan f  (cost=0.00..0.14 rows=2 width=4)
         Filter: ((k_dim / 10) > 0)*
         ->  *XN* *Seq Scan on fact_tbl rls_table  (cost=0.00..0.06 rows=5 width=8)
               Filter: (k_dim > 1)*
   ->  XN Hash  (cost=0.07..0.07 rows=2 width=8)
         ->  XN Seq Scan on dim_tbl d  (cost=0.00..0.07 rows=2 width=8)
               Filter: (("k" / 10) > 0)
```

在向用户授予 EXPLAIN RLS 权限的同时，Amazon Redshift 会在 STL\$1EXPLAIN 系统表中记录包括 RLS 谓词在内的完整查询计划。在未授予此权限时运行的查询将在没有 RLS 内部构件的情况下被记录。授予或删除 EXPLAIN RLS 权限不会改变 Amazon Redshift 为之前的查询记录到 STL\$1EXPLAIN 的内容。

### 受 AWS Lake Formation-RLS 保护的 Redshift 关系
<a name="r_EXPLAIN_RLS-LF"></a>

以下示例说明了 LF SecureScan 节点，您可以使用它来查看 Lake Formation-RLS 关系。

```
EXPLAIN
SELECT *
FROM lf_db.public.t_share
WHERE a > 1;
QUERY PLAN
---------------------------------------------------------------
XN LF SecureScan t_share  (cost=0.00..0.02 rows=2 width=11)
(2 rows)
```

## 示例
<a name="r_EXPLAIN-examples"></a>

**注意**  
对于这些示例，输出样本可能有所不同，具体取决于 Amazon Redshift 配置。

以下示例为从 EVENT 和 VENUE 表中选择 EVENTID、EVENTNAME、VENUEID 和 VENUENAME 的查询返回查询计划：

```
explain
select eventid, eventname, event.venueid, venuename
from event, venue
where event.venueid = venue.venueid;
```

```
                                QUERY PLAN
--------------------------------------------------------------------------
XN Hash Join DS_DIST_OUTER  (cost=2.52..58653620.93 rows=8712 width=43)
Hash Cond: ("outer".venueid = "inner".venueid)
->  XN Seq Scan on event  (cost=0.00..87.98 rows=8798 width=23)
->  XN Hash  (cost=2.02..2.02 rows=202 width=22)
->  XN Seq Scan on venue  (cost=0.00..2.02 rows=202 width=22)
(5 rows)
```

以下示例使用详细输出为同一查询返回查询计划：

```
explain verbose
select eventid, eventname, event.venueid, venuename
from event, venue
where event.venueid = venue.venueid;
```

```
                                QUERY PLAN
--------------------------------------------------------------------------
{HASHJOIN
:startup_cost 2.52
:total_cost 58653620.93
:plan_rows 8712
:plan_width 43
:best_pathkeys <>
:dist_info DS_DIST_OUTER
:dist_info.dist_keys (
TARGETENTRY
{
VAR
:varno 2
:varattno 1
...

XN Hash Join DS_DIST_OUTER  (cost=2.52..58653620.93 rows=8712 width=43)
Hash Cond: ("outer".venueid = "inner".venueid)
->  XN Seq Scan on event  (cost=0.00..87.98 rows=8798 width=23)
->  XN Hash  (cost=2.02..2.02 rows=202 width=22)
->  XN Seq Scan on venue  (cost=0.00..2.02 rows=202 width=22)
(519 rows)
```

以下示例返回 CREATE TABLE AS (CTAS) 语句的查询计划：

```
explain create table venue_nonulls as
select * from venue
where venueseats is not null;

QUERY PLAN
-----------------------------------------------------------
XN Seq Scan on venue  (cost=0.00..2.02 rows=187 width=45)
Filter: (venueseats IS NOT NULL)
(2 rows)
```

# FETCH
<a name="fetch"></a>

使用游标检索行。有关声明游标的信息，请参阅[DECLARE](declare.md)。

FETCH 根据游标中的当前位置检索行。在创建游标时，系统会将它放在第一行的前面。在执行 FETCH 后，系统会将游标放在检索的最后一行上。如果 FETCH 在运行时超出了可用行的结尾，例如跟在 FETCH ALL 后面，则游标会保留在最后一行的后面。

FORWARD 0 会提取当前行而不移动游标；即提取最近提取过的行。如果游标放在第一行的前面或最后一行的后面，则不返回任何行。

在提取游标的第一行时，会在领导节点上、内存中或磁盘上具体化整个结果集（如果需要）。由于将游标用于大型结果集可能会降低性能，因此建议使用备用方法（如果可能）。有关更多信息，请参阅 [使用游标时的性能注意事项](declare.md#declare-performance)。

有关更多信息，请参阅[DECLARE](declare.md)、[CLOSE](close.md)。

## 语法
<a name="fetch-synopsis"></a>

```
FETCH [ NEXT | ALL | {FORWARD [ count | ALL ] } ] FROM cursor
```

## 参数
<a name="fetch-parameters"></a>

NEXT  
提取下一行。这是默认模式。

ALL  
提取所有剩余的行。（与 FORWARD ALL 相同。） 对于单节点集群，不支持 ALL。

FORWARD [ *count* \$1 ALL ]   
提取后面 *count* 行，或者提取所有剩余的行。`FORWARD 0` 提取当前行。对于单节点集群，count 的最大值为 `1000`。对于单节点集群，不支持 FORWARD ALL。

*cursor*   
新游标的名称。

## FETCH 示例
<a name="fetch-example"></a>

以下示例声明一个名为 LOLLAPALOOZA 的游标，以便为 Lollapalooza 事件选择销售信息，然后使用该游标从结果集中提取行：

```
-- Begin a transaction

begin;

-- Declare a cursor

declare lollapalooza cursor for
select eventname, starttime, pricepaid/qtysold as costperticket, qtysold
from sales, event
where sales.eventid = event.eventid
and eventname='Lollapalooza';

-- Fetch the first 5 rows in the cursor lollapalooza:

fetch forward 5 from lollapalooza;

  eventname   |      starttime      | costperticket | qtysold
--------------+---------------------+---------------+---------
 Lollapalooza | 2008-05-01 19:00:00 |   92.00000000 |       3
 Lollapalooza | 2008-11-15 15:00:00 |  222.00000000 |       2
 Lollapalooza | 2008-04-17 15:00:00 |  239.00000000 |       3
 Lollapalooza | 2008-04-17 15:00:00 |  239.00000000 |       4
 Lollapalooza | 2008-04-17 15:00:00 |  239.00000000 |       1
(5 rows)

-- Fetch the next row:

fetch next from lollapalooza;

  eventname   |      starttime      | costperticket | qtysold
--------------+---------------------+---------------+---------
 Lollapalooza | 2008-10-06 14:00:00 |  114.00000000 |       2

-- Close the cursor and end the transaction:

close lollapalooza;
commit;
```

# GRANT
<a name="r_GRANT"></a>

为用户或角色定义访问权限。

权限包括各种访问选项，例如读取表和视图中的数据、写入数据、创建表和删除表的功能。使用此命令可授予对表、数据库、架构、函数、过程、语言或列的特定权限。要撤销对数据库对象的权限，请使用 [REVOKE](r_REVOKE.md) 命令。

权限还包括以下数据共享生产者访问选项：
+  向使用者命名空间和账户授予数据共享访问权限。
+  通过在数据共享中添加或删除对象来授予更改数据共享的权限。
+  通过在数据共享中添加或删除使用者命名空间来授予共享数据共享的权限。

数据共享使用者访问选项如下：
+ 向用户授予对通过数据共享创建的数据库或指向此类数据库的外部架构的完全访问权限。
+ 向用户授予对通过数据共享创建的数据库的对象级权限，就像对本地数据库对象一样。要授予此级别的权限，在从数据共享创建数据库时必须使用 WITH PERMISSIONS 子句。有关更多信息，请参阅 [CREATE DATABASE](r_CREATE_DATABASE.md)。

有关数据共享权限的更多信息，请参阅[您可以向数据共享授予的权限](permissions-datashares.md)。

权限还包括以下 Amazon Redshift 联合身份验证权限目录：
+ 向用户和角色授予表级别权限。
+ 授予对表、视图和实体化视图的精细列级别权限。
+ 向用户和角色授予限定范围权限。
+ 授予对 Amazon Redshift 联合身份验证权限目录的数据库级别权限。

有关管理对 Amazon Redshift 联合身份验证权限目录的权限的更多信息，请参阅[管理 Amazon Redshift 联合身份验证权限目录上的访问控制授权/撤销](federated-permissions-managing-access.md)。有关 Amazon Redshift 联合身份验证权限目录支持的授予/撤销语法的更多信息，请参阅[授予/撤销](https://docs.aws.amazon.com/redshift/latest/dg/federated-permissions-managing-access.html#federated-permissions-managing-access-grant-revoke)。

权限还包括 AWS IAM Identity Center 联合用户的 CONNECT 权限。此权限使管理员能够在每个已启用 Amazon Redshift 联合身份验证权限的 Amazon Redshift 工作组或集群中，通过精细权限控制用户访问权限。Amazon Redshift 管理员可以指定哪些 AWS IAM Identity Center 联合用户或组有权直接连接到 Amazon Redshift 工作组，从而提供对每个工作组或集群上的 AWS IAM Identity Center 用户访问权限的精细控制。

您还可以授予角色来管理数据库权限，以及控制用户可以对您的数据执行的操作。通过定义角色并向用户分配角色，您可以限制这些用户能够执行的操作，例如限制用户只能使用 CREATE TABLE 和 INSERT 命令。有关 CREATE ROLE 命令的更多信息，请参阅 [CREATE ROLE](r_CREATE_ROLE.md)。Amazon Redshift 有一些系统定义的角色，您也可以使用这些角色向用户授予特定权限。有关更多信息，请参阅 [Amazon Redshift 系统定义的角色](r_roles-default.md)。

您只能将对于外部架构的 GRANT 或 REVOKE USAGE 权限授予使用 ON SCHEMA 语法的数据库用户和用户组。将 ON EXTERNAL SCHEMA 与 AWS Lake Formation 搭配使用时，您只能向 AWS Identity and Access Management (IAM) 角色授予 GRANT 和 REVOKE 权限。有关权限的列表，请参阅“语法”。

对于存储过程，唯一可以授予的权限是 EXECUTE。

您不能在以下事务数据块内的（外部资源）上运行 GRANT：(BEGIN ... END)。有关事务的更多信息，请参阅 [Amazon Redshift 中的隔离级别](c_serial_isolation.md)。

要查看已向用户授予了数据库的哪些权限，请使用 [HAS\$1DATABASE\$1PRIVILEGE](r_HAS_DATABASE_PRIVILEGE.md)。要查看已向用户授予了针对架构的哪些权限，请使用 [HAS\$1SCHEMA\$1PRIVILEGE](r_HAS_SCHEMA_PRIVILEGE.md)。要查看已向用户授予了表的哪些权限，请使用 [HAS\$1TABLE\$1PRIVILEGE](r_HAS_TABLE_PRIVILEGE.md)。

## 语法
<a name="r_GRANT-synopsis"></a>



```
GRANT { { SELECT | INSERT | UPDATE | DELETE | DROP | REFERENCES | ALTER | TRUNCATE } [,...] | ALL [ PRIVILEGES ] }
    ON { [ TABLE ] table_name [, ...] | ALL TABLES IN SCHEMA schema_name [, ...] }
    TO { username [ WITH GRANT OPTION ] | ROLE role_name | GROUP group_name | PUBLIC } [, ...]

GRANT { { CREATE | USAGE | TEMPORARY | TEMP | ALTER } [,...] | ALL [ PRIVILEGES ] }
    ON DATABASE db_name [, ...]
    TO { username [ WITH GRANT OPTION ] | ROLE role_name | GROUP group_name | PUBLIC } [, ...]

GRANT { { CREATE | USAGE | ALTER | DROP } [,...] | ALL [ PRIVILEGES ] }
    ON SCHEMA schema_name [, ...]
    TO { username [ WITH GRANT OPTION ] | ROLE role_name | GROUP group_name | PUBLIC } [, ...]

GRANT { EXECUTE | ALL [ PRIVILEGES ] }
    ON { FUNCTION function_name ( [ [ argname ] argtype [, ...] ] ) [, ...] | ALL FUNCTIONS IN SCHEMA schema_name [, ...] }
    TO { username [ WITH GRANT OPTION ] | ROLE role_name | GROUP group_name | PUBLIC } [, ...]

GRANT { EXECUTE | ALL [ PRIVILEGES ] }
    ON { PROCEDURE procedure_name ( [ [ argname ] argtype [, ...] ] ) [, ...] | ALL PROCEDURES IN SCHEMA schema_name [, ...] }
    TO { username [ WITH GRANT OPTION ] | ROLE role_name | GROUP group_name | PUBLIC } [, ...]

GRANT USAGE
    ON LANGUAGE language_name [, ...]
    TO { username [ WITH GRANT OPTION ] | ROLE role_name | GROUP group_name | PUBLIC } [, ...]             

GRANT { { ALTER | DROP} [,...] | ALL [ PRIVILEGES ] }
    ON COPY JOB job_name [,...]
    TO { username [ WITH GRANT OPTION ] | ROLE role_name | GROUP group_name | PUBLIC } [, ...]

GRANT { { ALTER | DROP | USAGE } [,...] | ALL [ PRIVILEGES ] }
    ON TEMPLATE [database_name.][schema_name.]template_name [,...]
    TO { username [ WITH GRANT OPTION ] | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
```

### 授予表的列级别权限
<a name="grant-column-level"></a>

以下是 Amazon Redshift 表和视图上的列级别权限的语法。

```
GRANT { { SELECT | UPDATE } ( column_name [, ...] ) [, ...] | ALL [ PRIVILEGES ] ( column_name [,...] ) }
     ON { [ TABLE ] table_name [, ...] }

     TO { username | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
```

### 授予 ASSUMEROLE 权限
<a name="grant-assumerole-permissions"></a>

以下是向具有指定角色的用户和组授予 ASSUMEROLE 权限的语法。要开始使用 ASSUMEROLE 权限，请参阅[有关授予 ASSUMEROLE 权限的使用说明](r_GRANT-usage-notes.md#r_GRANT-usage-notes-assumerole)。

```
GRANT ASSUMEROLE
       ON { 'iam_role' [, ...] | default | ALL }
       TO { username | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
       FOR { ALL | COPY | UNLOAD | EXTERNAL FUNCTION | CREATE MODEL } [, ...]
```

### 授予将 Redshift Spectrum 与 Lake Formation 集成的权限
<a name="grant-spectrum-integration-with-lf-syntax"></a>

以下是 Redshift Spectrum 与 Lake Formation 集成的语法。

```
GRANT { SELECT | ALL [ PRIVILEGES ] } ( column_list )
    ON EXTERNAL TABLE schema_name.table_name
    TO { IAM_ROLE iam_role } [, ...] [ WITH GRANT OPTION ]

GRANT { { SELECT | ALTER | DROP | DELETE | INSERT }  [, ...] | ALL [ PRIVILEGES ] }
    ON EXTERNAL TABLE schema_name.table_name [, ...]
    TO { { IAM_ROLE iam_role } [, ...] | PUBLIC } [ WITH GRANT OPTION ]

GRANT { { CREATE | ALTER | DROP }  [, ...] | ALL [ PRIVILEGES ] }
    ON EXTERNAL SCHEMA schema_name [, ...]
    TO { IAM_ROLE iam_role } [, ...] [ WITH GRANT OPTION ]
```

### 授予数据共享权限
<a name="grant-datashare-syntax"></a>

**生产者端数据共享权限**  
以下是使用 GRANT 向用户或角色授予 ALTER 或 SHARE 权限的语法。用户可以使用 ALTER 权限更改数据共享，也可以向具有 SHARE 权限的使用者授予使用权限。您只能向用户和角色授予对数据共享的 ALTER 和 SHARE 权限。

```
GRANT { ALTER | SHARE } ON DATASHARE datashare_name
    TO { username [ WITH GRANT OPTION ] | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
```

以下是使用 GRANT 授予 Amazon Redshift 上的数据共享使用权限的语法。您可以使用 USAGE 权限向使用者授予对数据共享的访问权限。您不能将此权限授予用户或用户组。此权限也不支持 GRANT 语句的 WITH GRANT OPTION。只有具有先前针对数据共享授予了他们 SHARE 权限的用户或用户组才能运行此类型的 GRANT 语句。

```
GRANT USAGE
    ON DATASHARE datashare_name
    TO NAMESPACE 'namespaceGUID' | ACCOUNT 'accountnumber' [ VIA DATA CATALOG ]
```

以下是如何向 Lake Formation 账户授予数据共享使用权的一个示例。

```
GRANT USAGE ON DATASHARE salesshare TO ACCOUNT '123456789012' VIA DATA CATALOG;
```

**使用者端数据共享权限**  
以下是根据数据共享创建的特定数据库或 schema 的 GRANT 数据共享使用权限的语法。

使用者访问通过数据共享创建的数据库所需的其他权限会有所不同，具体取决于用于从数据共享创建数据库的 CREATE DATABASE 命令是否使用 WITH PERMISSIONS 子句。有关 CREATE DATABASE 命令和 WITH PERMISSIONS 子句的更多信息，请参阅[CREATE DATABASE](r_CREATE_DATABASE.md)。

**未使用 WITH PERMISSIONS 子句创建的数据库**  
在不使用 WITH PERMISSIONS 子句的情况下，对通过数据共享创建的数据库授予 USAGE 权限时，无需对共享数据库中的对象单独授予权限。在不使用 WITH PERMISSIONS 子句的情况下，获准使用从数据共享创建的数据库的实体可以自动访问数据库中的所有对象。

**使用 WITH PERMISSIONS 子句创建的数据库**  
如果共享数据库是使用 WITH PERMISSIONS 子句从数据共享中创建的，则在授予数据库 USAGE 权限时，使用者端实体仍必须获得共享数据库中数据库对象的相关权限才能访问这些对象，就像对本地数据库对象授予权限一样。要向通过数据共享创建的数据库中的对象授予权限，请使用由三部分组成的语法 `database_name.schema_name.object_name`。要向外部架构中指向共享数据库中共享架构的对象授予权限，请使用由两部分组成的语法 `schema_name.object_name`。

```
GRANT USAGE ON { DATABASE shared_database_name [, ...] | SCHEMA shared_schema}
    TO { username | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
```

### 授予限定范围权限
<a name="grant-scoped-syntax"></a>

限定范围权限允许您向用户或角色授予对数据库或架构中某一类型的所有对象的访问权限。具有限定范围权限的用户和角色对数据库或架构中的所有当前和未来对象具有指定权限。

您可以在 [SVV\$1DATABASE\$1PRIVILEGES](r_SVV_DATABASE_PRIVILEGES.md) 中查看数据库级限定权限的范围。您可以在 [SVV\$1SCHEMA\$1PRIVILEGES](r_SVV_SCHEMA_PRIVILEGES.md) 中查看架构级限定权限的范围。

有关限定范围权限的更多信息，请参阅[限定范围权限](t_scoped-permissions.md)。

以下是向用户和角色授予限定范围权限的语法。

```
GRANT { CREATE | USAGE | ALTER | DROP } [,...] | ALL [ PRIVILEGES ] }
FOR SCHEMAS IN
DATABASE db_name 
TO { username [ WITH GRANT OPTION ] | ROLE role_name } [, ...]

GRANT 
{ { SELECT | INSERT | UPDATE | DELETE | DROP | ALTER | TRUNCATE | REFERENCES } [, ...] } | ALL [PRIVILEGES] } }
FOR TABLES IN
{SCHEMA schema_name [DATABASE db_name ] | DATABASE db_name }
TO { username [ WITH GRANT OPTION ] | ROLE role_name} [, ...]

GRANT { EXECUTE | ALL [ PRIVILEGES ] }
FOR FUNCTIONS IN 
{SCHEMA schema_name [DATABASE db_name ] | DATABASE db_name }
TO { username [ WITH GRANT OPTION ] | ROLE role_name | } [, ...]

GRANT { EXECUTE | ALL [ PRIVILEGES ] }
FOR PROCEDURES IN
{SCHEMA schema_name [DATABASE db_name ] | DATABASE db_name }
TO { username [ WITH GRANT OPTION ] | ROLE role_name | } [, ...]

GRANT USAGE
FOR LANGUAGES IN
{DATABASE db_name}
TO { username [ WITH GRANT OPTION ] | ROLE role_name } [, ...]  

GRANT { { CREATE | ALTER | DROP} [,...] | ALL [ PRIVILEGES ] }
FOR COPY JOBS 
IN DATABASE db_name
TO { username [ WITH GRANT OPTION ] | ROLE role_name } [, ...]

GRANT { { ALTER | DROP | USAGE } [,...] | ALL [ PRIVILEGES ] }
FOR TEMPLATES IN
{SCHEMA schema_name [DATABASE db_name ] | DATABASE db_name }
TO { username [ WITH GRANT OPTION ] | ROLE role_name } [, ...]
```

请注意，范围限定的权限不区分函数的权限和过程的权限。例如，以下语句授予 `bob` 对架构 `Sales_schema` 中函数和过程的 `EXECUTE` 权限。

```
GRANT EXECUTE FOR FUNCTIONS IN SCHEMA Sales_schema TO bob;
```

### 授予机器学习权限
<a name="grant-model-syntax"></a>

以下是有关 Amazon Redshift 上机器学习模型权限的语法。

```
GRANT CREATE MODEL
    TO { username [ WITH GRANT OPTION ] | ROLE role_name | GROUP group_name | PUBLIC } [, ...]

GRANT { EXECUTE | ALL [ PRIVILEGES ] }
    ON MODEL model_name [, ...]

    TO { username [ WITH GRANT OPTION ] | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
```

### 授予角色权限
<a name="grant-roles"></a>

以下是在 Amazon Redshift 中授予角色的语法。

```
GRANT { ROLE role_name } [, ...] TO { { user_name [ WITH ADMIN OPTION ] } | ROLE role_name }[, ...]
```

以下是向角色授予对 Amazon Redshift 的系统权限的语法。请注意，您只能向角色授予权限，而不能向用户授予权限。

```
GRANT
  {
    { CREATE USER | DROP USER | ALTER USER |
    CREATE SCHEMA | DROP SCHEMA |
    ALTER DEFAULT PRIVILEGES |
    ACCESS CATALOG | ACCESS SYSTEM TABLE
    CREATE TABLE | DROP TABLE | ALTER TABLE |
    CREATE OR REPLACE FUNCTION | CREATE OR REPLACE EXTERNAL FUNCTION |
    DROP FUNCTION |
    CREATE OR REPLACE PROCEDURE | DROP PROCEDURE |
    CREATE OR REPLACE VIEW | DROP VIEW |
    CREATE MODEL | DROP MODEL |
    CREATE DATASHARE | ALTER DATASHARE | DROP DATASHARE |
    CREATE LIBRARY | DROP LIBRARY |
    CREATE ROLE | DROP ROLE |
    TRUNCATE TABLE
    VACUUM | ANALYZE | CANCEL |
    IGNORE RLS | EXPLAIN RLS | 
    EXPLAIN MASKING }[, ...]
  }
  | { ALL [ PRIVILEGES ] }
TO ROLE role_name [, ...]
```

### 授予对安全性策略的解释权限
<a name="grant-row-level-security"></a>

以下语法用于授予解释 EXPLAIN 计划中查询的安全性策略筛选条件的权限。可能的安全性策略包括行级安全性策略和动态数据掩蔽策略。

```
GRANT EXPLAIN { RLS | MASKING } TO ROLE rolename 
```

以下语法用于授予为查询绕开行级别安全性策略的权限。此语法不适用于动态数据掩蔽策略。

```
GRANT IGNORE RLS TO ROLE rolename 
```

以下语法用于授予对指定安全性策略的查找表权限。可能的安全性策略包括行级安全性策略和动态数据掩蔽策略。

```
GRANT SELECT ON [ TABLE ] table_name [, ...]
TO { RLS | MASKING } POLICY policy_name [, ...]
```

### 授予连接权限
<a name="grant-connection-permissions"></a>

以下语法用于向 AWS IAM Identity Center 联合用户（或组）授予连接到工作组/集群的权限：

```
GRANT CONNECT [ON WORKGROUP]
TO [USER] <prefix>:<username> | ROLE <prefix>:<rolename> | PUBLIC;
```

## 参数
<a name="r_GRANT-parameters"></a>

SELECT   <a name="grant-select"></a>
授予使用 SELECT 语句从表或视图中选择数据的权限。对于 UPDATE 或 DELETE 操作，也需要 SELECT 权限来引用现有的列值。

INSERT   <a name="grant-insert"></a>
授予使用 INSERT 语句或 COPY 语句将数据加载到表中的权限。

UPDATE   <a name="grant-update"></a>
授予使用 UPDATE 语句更新表列的权限。UPDATE 操作也需要 SELECT 权限，因为这些操作必须引用表列才能确定要更新哪些行或者计算列的新值。

DELETE  <a name="grant-delete"></a>
授予从表中删除数据行的权限。DELETE 操作也需要 SELECT 权限，因为这些操作必须引用表列才能确定要删除哪些行。

DROP  <a name="grant-drop"></a>
根据数据库对象，向用户或角色授予以下权限：  
+  对于表，DROP 授予删除表或视图的权限。有关更多信息，请参阅 [DROP TABLE](r_DROP_TABLE.md)。
+  对于数据库，DROP 授予删除数据库的权限。有关更多信息，请参阅 [DROP DATABASE](r_DROP_DATABASE.md)。
+  对于架构，DROP 授予删除架构的权限。有关更多信息，请参阅 [DROP SCHEMA](r_DROP_SCHEMA.md)。

REFERENCES   <a name="grant-references"></a>
授予创建外键约束的权限。您必须授予对被引用表和引用表的此权限；否则，用户将无法创建约束。

ALTER  <a name="grant-alter"></a>
根据数据库对象，向用户或用户组授予以下权限：  
+ 对于表，ALTER 授予更改表或视图的权限。有关更多信息，请参阅 [ALTER TABLE](r_ALTER_TABLE.md)。
+ 对于数据库，ALTER 授予更改数据库的权限。有关更多信息，请参阅 [ALTER DATABASE](r_ALTER_DATABASE.md)。
+ 对于模式，ALTER 授予更改模式的权限。有关更多信息，请参阅 [ALTER SCHEMA](r_ALTER_SCHEMA.md)。
+ 对于外部表，ALTER 授予对为 Lake Formation 启用的 AWS Glue Data Catalog 中的表进行更改的权限。此权限仅在使用 Lake Formation 时适用。

TRUNCATE  <a name="grant-truncate"></a>
授予截断表的权限。如果没有此权限，则只有表的拥有者或超级用户才可以截断表。有关 TRUNCATE 命令的更多信息，请参阅 [TRUNCATE](r_TRUNCATE.md)。

ALL [ PRIVILEGES ]   <a name="grant-all"></a>
一次性向指定的用户或角色授予所有可用权限。PRIVILEGES 关键字是可选的。  
GRANT ALL ON SCHEMA 不会授予对外部架构的 CREATE 权限。  
您可以针对为 Lake Formation 启用的 AWS Glue Data Catalog 中的表授予 ALL 权限。在这种情况下，各个权限（如 SELECT、ALTER 等）将记录在 Data Catalog 中。  
 Amazon Redshift 不支持 RULE 和 TRIGGER 权限。有关更多信息，请转至 [不支持的 PostgreSQL 功能](c_unsupported-postgresql-features.md)。

ASSUMEROLE  <a name="assumerole"></a>
向具有指定角色的用户、角色或组授予运行 COPY、UNLOAD、EXTERNAL FUNCTION 和 CREATE MODEL 命令的权限。用户、角色或组在运行指定的命令时代入该角色。要开始使用 ASSUMEROLE 权限，请参阅[有关授予 ASSUMEROLE 权限的使用说明](r_GRANT-usage-notes.md#r_GRANT-usage-notes-assumerole)。

ON [ TABLE ] *table\$1name*   <a name="grant-on-table"></a>
授予对表或视图的指定权限。TABLE 关键字是可选的。您可以在一个语句中列出多个表和视图。

ON ALL TABLES IN SCHEMA *schema\$1name*   <a name="grant-all-tables"></a>
授予对被引用架构中的所有表和视图的指定权限。

( *column\$1name* [,...] ) ON TABLE *table\$1name*   <a name="grant-column-level-privileges"></a>
向用户、组或 PUBLIC 授予对 Amazon Redshift 表或视图的指定列的指定权限。

( *column\$1list* ) ON EXTERNAL TABLE *schema\$1name.table\$1name*   <a name="grant-external-table-column"></a>
向 IAM 角色授予对引用架构中 Lake Formation 表的指定列的指定权限。

ON EXTERNAL TABLE *schema\$1name.table\$1name*   <a name="grant-external-table"></a>
向 IAM 角色授予对引用架构中指定 Lake Formation 表的指定权限。

ON EXTERNAL SCHEMA *schema\$1name*   <a name="grant-external-schema"></a>
向 IAM 角色授予对引用架构的指定权限。

ON *iam\$1role*   <a name="grant-iam_role"></a>
向 IAM 角色授予指定权限。

TO *username*   <a name="grant-to"></a>
指示接收权限的用户。

TO IAM\$1ROLE *iam\$1role*   <a name="grant-to-iam-role"></a>
指示接收权限的 IAM 角色。

WITH GRANT OPTION   <a name="grant-with-grant"></a>
指示接收权限的用户随之可以将相同的权限授予其他用户。您无法将 WITH GRANT OPTION 授予组或 PUBLIC。

ROLE *role\$1name*   <a name="grant-role"></a>
将权限授予角色。

GROUP *group\$1name*   <a name="grant-group"></a>
将权限授予用户组。可以是逗号分隔的列表，用于指定多个用户组。

PUBLIC   <a name="grant-public"></a>
向所有用户授予指定的权限，包括以后创建的用户。PUBLIC 表示一个始终包含所有用户的组。单个用户的权限包含向 PUBLIC 授予的权限、向用户所属的所有组授予的权限以及向用户单独授予的任何权限。  
将 PUBLIC 授予 Lake Formation EXTERNAL TABLE 会将权限授予 Lake Formation *所有人*组。

CONNECT [ON WORKGROUP] TO \$1 [USER] <prefix>:<username> \$1 ROLE <prefix>:<rolename> \$1 PUBLIC \$1  
向 AWS IAM Identity Center 联合用户或组授予连接到工作组或集群的权限。该前缀标识身份提供者。在将权限授予 PUBLIC 后，该权限将适用于所有 AWS IAM Identity Center 联合用户，包括以后创建的用户。只有在工作组或集群上启用了 Amazon Redshift 联合身份验证权限时，此权限才适用。

CREATE   <a name="grant-create"></a>
根据数据库对象，向用户或用户组授予以下权限：  
+ 对于数据库，CREATE 允许用户在数据库中创建 schemas。
+ 对于 schema，CREATE 允许用户在 schema 中创建对象。要重命名对象，用户必须具有 CREATE 权限并拥有要重命名的对象。
+ Amazon Redshift Spectrum 外部 schema 不支持 CREATE ON SCHEMA。要授予在外部 schema 中使用外部表的权限，请向需要访问权限的用户授予 USAGE ON SCHEMA。仅允许外部 schema 的所有者或超级用户在外部 schema 中创建外部表。要移交外部 schema 的所有权，请使用 [ALTER SCHEMA](r_ALTER_SCHEMA.md) 更改所有者。

TEMPORARY \$1 TEMP   <a name="grant-temporary"></a>
授予在指定的数据库中创建临时表的权限。要运行 Amazon Redshift Spectrum 查询，数据库用户必须有权在数据库中创建临时表。  
默认情况下，向用户授予权限以通过其在 PUBLIC 组中自动获得的成员资格来创建临时表。要删除任何用户创建临时表的权限，请撤销 PUBLIC 组的 TEMP 权限。然后，明确授予特定用户或用户组创建临时表的权限。

ON DATABASE *db\$1name*   <a name="grant-database"></a>
授予对数据库的指定权限。

USAGE   <a name="grant-usage"></a>
授予对特定架构的 USAGE 权限，这将使用户能够访问该架构中的对象。必须单独为本地 Amazon Redshift 架构授予对这些对象执行特定操作的权限（例如，对表的 SELECT 或 UPDATE 权限）。默认情况下，所有用户都对 PUBLIC 架构具有 CREATE 和 USAGE 权限。  
 使用 ON SCHEMA 语法向外部 Schema 授予 USAGE 权限时，无需单独授予对外部 Schema 中对象的操作。相应的目录权限控制对外部 Schema 对象的细粒度权限。

ON SCHEMA *schema\$1name*   <a name="grant-schema"></a>
授予对数据库的指定权限。  
Amazon Redshift Spectrum 外部架构不支持 GRANT ALL ON SCHEMA 中的 GRANT CREATE ON SCHEMA 和 CREATE 权限。要授予在外部 schema 中使用外部表的权限，请向需要访问权限的用户授予 USAGE ON SCHEMA。仅允许外部 schema 的所有者或超级用户在外部 schema 中创建外部表。要移交外部 schema 的所有权，请使用 [ALTER SCHEMA](r_ALTER_SCHEMA.md) 更改所有者。

EXECUTE ON ALL FUNCTIONS IN SCHEMA *schema\$1name*  <a name="grant-all-functions"></a>
授予对被引用架构中的所有函数的指定权限。  
对于在 pg\$1catalog 命名空间中定义的 pg\$1proc 内置条目，Amazon Redshift 不支持 GRANT 或 REVOKE 语句。

EXECUTE ON PROCEDURE *procedure\$1name*   <a name="grant-procedure"></a>
授予对特定存储过程的 EXECUTE 权限。由于存储过程名称可重载，因此您必须包含过程的参数列表。有关更多信息，请参阅 [命名存储过程](stored-procedure-naming.md)。

EXECUTE ON ALL PROCEDURES IN SCHEMA *schema\$1name*  <a name="grant-all-procedures"></a>
授予对被引用架构中所有存储过程的指定权限。

USAGE ON LANGUAGE *language\$1name*   
授予对某种语言的 USAGE 权限。  
从 2025 年 11 月 1 日起，Amazon Redshift 将不再支持创建新的 Python UDF。现有的 Python UDF 将继续正常运行至 2026 年 6 月 30 日。从 2026 年 7 月 1 日起，Amazon Redshift 将不再支持 Python UDF。我们建议您在 2025 年 11 月 1 日之前，将现有 Python UDF 迁移到 Lambda UDF。有关创建和使用 Lambda UDF 的信息，请参阅[标量 Lambda UDF](udf-creating-a-lambda-sql-udf.md)。有关将现有 Python UDF 转换为 Lambda UDF 的信息，请参阅[博客文章](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)。
需要 USAGE ON LANGUAGE 权限才能运行 [CREATE FUNCTION](r_CREATE_FUNCTION.md) 命令来创建用户定义函数 (UDF)。有关更多信息，请参阅 [UDF 安全性和权限](udf-security-and-privileges.md)。  
需要 USAGE ON LANGUAGE 权限才能通过运行 [CREATE PROCEDURE](r_CREATE_PROCEDURE.md) 命令来创建存储过程。有关更多信息，请参阅 [存储过程的安全性和权限](stored-procedure-security-and-privileges.md)。  
对于 Python UDF，使用 `plpythonu`。对于 SQL UDF，使用 `sql`。对于存储过程，请使用 `plpgsql`。

ON COPY JOB *job\$1name*  <a name="on-copy-job"></a>
授予对复制作业的指定权限。

FOR \$1 ALL \$1 COPY \$1 UNLOAD \$1 EXTERNAL FUNCTION \$1 CREATE MODEL \$1 [, ...]   <a name="grant-for"></a>
指定被授予权限的 SQL 命令。您可以指定 ALL 以授予对 COPY、UNLOAD、EXTERNAL FUNCTION 和 CREATE MODEL 语句的权限。此子句仅适用于授予 ASSUMEROLE 权限。

ALTER  
向用户授予 ALTER 权限，以便将对象添加到数据共享中或从中删除，或设置属性 PUBLICACCESSIBLE。有关更多信息，请参阅 [ALTER DATASHARE](r_ALTER_DATASHARE.md)。

SHARE  
向用户和用户组授予将数据使用者添加到数据共享的权限。要使特定使用者（账户或命名空间）能够从其集群访问数据共享，需要此权限。使用者可以相同或不同的 AWS 账户，集群命名空间与全局唯一标识符 (GUID) 指定的集群命名空间相同或不同。

ON DATASHARE *datashare\$1name*   <a name="grant-datashare"></a>
授予对被引用数据共享的指定权限。有关使用者访问控制粒度的信息，请参阅 [Amazon Redshift 中不同级别的数据共享](datashare-overview.md#granularity)。

USAGE  
将 USAGE 授予同一账户中的使用者账户或命名空间时，该账户中的特定使用者账户或命名空间可以以只读方式访问数据共享和数据共享的对象。

TO NAMESPACE 'clusternamespace GUID'  
指示同一账户中的一个命名空间，使用者可以在其中接收对数据共享的指定权限。命名空间使用 128 位的字符数字 GUID。

TO ACCOUNT 'accountnumber' [ VIA DATA CATALOG ]  
指示使用者可以在其中接收对数据共享的指定权限的另一个账号。指定‘VIA DATA CATALOG’表示向 Lake Formation 账户授予使用数据共享的权限。省略此参数意味着您向拥有该集群的账户授予使用权限。

ON DATABASE *shared\$1database\$1name> [, ...]*   <a name="grant-datashare"></a>
授予对在指定数据共享中创建的指定数据库的指定使用权限。

ON SCHEMA* shared\$1schema*   <a name="grant-datashare"></a>
授予对在指定数据共享中创建的指定架构的指定权限。

FOR \$1 SCHEMAS \$1 TABLES \$1 FUNCTIONS \$1 PROCEDURES \$1 LANGUAGES \$1 COPY JOBS\$1 IN   
指定要向其授予权限的数据库对象。IN 后面的参数定义了所授予权限的范围。

CREATE MODEL  
向特定用户或用户组授予 CREATE MODEL 权限。

ON MODEL *model\$1name*  
授予对特定模型的 EXECUTE 权限。

ACCESS CATALOG  
授予查看该角色可访问对象的相关元数据的权限。

\$1 role \$1 [, ...]  
要向其他角色、用户或 PUBLIC 授予的角色。  
PUBLIC 表示一个始终包含所有用户的组。单个用户的权限包含向 PUBLIC 授予的权限、向用户所属的所有组授予的权限以及向用户单独授予的任何权限。

TO \$1 \$1 *user\$1name* [ WITH ADMIN OPTION ] \$1 \$1 role \$1[, ...]  
将指定角色授予具有 WITH ADMIN OPTION 权限的指定用户、其他角色或 PUBLIC。  
WITH ADMIN OPTION 条件句会向所有被授予者提供所有授予的角色的管理选项。

EXPLAIN \$1 RLS \$1 MASKING \$1 TO ROLE *rolename*  
向角色授予解释 EXPLAIN 计划中查询的安全性策略筛选条件的权限。RLS 授予解释行级安全性策略筛选条件的权限。MASKING 授予解释动态数据掩蔽策略筛选条件的权限。

IGNORE RLS TO ROLE *rolename*   
向角色授予绕开某个查询的行级别安全性策略的权限。

TO \$1 RLS \$1 MASKING \$1 POLICY *policy\$1name*  
指示接收权限的安全性策略。TO RLS POLICY 表示行级安全性策略。TO MASKING POLICY 表示动态数据掩蔽策略。

## 使用说明
<a name="r_GRANT-usage-notes-link"></a>

要了解有关 GRANT 使用说明的更多信息，请参阅[使用说明](r_GRANT-usage-notes.md)。

## 示例
<a name="r_GRANT-examples-link"></a>

有关如何使用 GRANT 的示例，请参阅[示例](r_GRANT-examples.md)。

# 使用说明
<a name="r_GRANT-usage-notes"></a>

要授予关于对象的权限，您必须满足以下条件之一：
+ 是对象所有者。
+ 是超级用户。
+ 拥有该对象和权限的授予权限。

例如，以下命令使用户 HR 能够对 employees 表执行 SELECT 命令并对其他用户授予和撤销相同的权限。

```
grant select on table employees to HR with grant option;
```

HR 无法授予 SELECT 之外的任何操作的权限或 employees 表之外的任何其他表的权限。

再例如，以下命令使用户 HR 能够对 employees 表执行 ALTER 命令并对其他用户授予和撤销相同的权限。

```
grant ALTER on table employees to HR with grant option;
```

HR 无法授予除 ALTER 之外的任何操作的权限或 employees 表之外的任何其他表的权限。

获得视图的权限并不意味着对基础表具有权限。同样，获得 schema 的权限并不意味着对该 schema 中的表具有权限。而是显式授予对基础表的访问权限。

要授予针对 AWS Lake Formation 表的权限，与表的外部架构关联的 IAM 角色必须有权授予对外部表的权限。以下示例创建具有关联 IAM 角色 `myGrantor` 的外部架构。IAM 角色 `myGrantor` 有权向其他角色授予权限。GRANT 命令使用与外部架构关联的 IAM 角色 `myGrantor` 的权限来向 IAM 角色 `myGrantee` 授予权限。

```
create external schema mySchema
from data catalog
database 'spectrum_db'
iam_role 'arn:aws:iam::123456789012:role/myGrantor'
create external database if not exists;
```

```
grant select
on external table mySchema.mytable
to iam_role 'arn:aws:iam::123456789012:role/myGrantee';
```

如果您向 IAM 角色授予 ALL 权限，则会在相关的启用了 Lake Formation 的 Data Catalog 中授予各个权限。例如，以下 GRANT ALL 会导致在 Lake Formation 控制台中显示授予的各个权限（SELECT、ALTER、DROP、DELETE 和 INSERT）。

```
grant all
on external table mySchema.mytable
to iam_role 'arn:aws:iam::123456789012:role/myGrantee';
```

超级用户可以访问所有对象，不管设置对象权限的 GRANT 和 REVOKE 命令如何。

## 列级访问控制的使用说明
<a name="r_GRANT-usage-notes-clp"></a>

以下使用说明适用于 Amazon Redshift 表和视图上的列级权限。这些说明描述了表；除非我们明确指出例外，否则相同的说明适用于视图。
+ 对于 Amazon Redshift 表，您只能在列级别授予 SELECT 和 UPDATE 权限。对于 Amazon Redshift 视图，您只能在列级别授予 SELECT 权限。
+ ALL 关键字是在表上列级 GRANT 的上下文中使用时组合的 SELECT 和 UPDATE 权限的同义词。
+ 如果您没有表中所有列的 SELECT 权限，则执行 SELECT \$1 操作将仅返回您有权访问的那些列。使用视图时，SELECT \$1 操作会尝试访问视图中的所有列。如果您并没有访问所有列的权限，则这些查询会失败，并出现权限被拒绝错误。
+ 在以下情况下，SELECT \$1 不会仅扩展到可访问的列：
  + 您无法使用 SELECT \$1 创建仅包含可访问列的常规视图。
  + 您无法使用 SELECT \$1 创建仅包含可访问列的实体化视图。
+ 如果对表或视图具有 SELECT 或 UPDATE 权限并添加一列，则您对表或视图及其所有列仍具有相同的权限。
+ 只有表的拥有者或超级用户才能授予列级权限。
+ 列级权限不支持 WITH GRANT OPTION 子句。
+ 您不能同时在表级别和列级别保持相同的权限。例如，用户 `data_scientist` 不能既对表 `employee` 具有 SELECT 权限，又对列 `employee.department` 具有 SELECT 权限。在对表和表中的列授予相同权限时，请考虑以下结果：
  + 如果用户对表具有表级权限，则在列级别授予相同权限不起作用。
  + 如果用户对表具有表级权限，则撤消表中一个或多个列的相同权限将返回错误。而应撤消表级别的权限。
  + 如果用户具有列级权限，则在表级别授予相同权限将返回错误。
  + 如果用户具有列级权限，则在表级别撤消相同的权限将撤消对表上所有列的列和表权限。
+ 您不能为后期绑定视图授予列级权限。
+ 要创建实体化视图，您必须对基表具有表级 SELECT 权限。即使您对特定列具有列级权限，也无法仅在这些列上创建实体化视图。但是，您可以授予对于实体化视图（类似于常规视图）的列的 SELECT 权限。
+ 要查找列级别权限的授予，请使用 [PG\$1ATTRIBUTE\$1INFO](r_PG_ATTRIBUTE_INFO.md) 视图。

## 有关授予 ASSUMEROLE 权限的使用说明
<a name="r_GRANT-usage-notes-assumerole"></a>

以下使用说明适用于在 Amazon Redshift 中授予 ASSUMEROLE 权限。

您可以使用 ASSUMEROLE 权限，通过 IAM 角色控制数据库用户、角色或组对 COPY、UNLOAD、EXTERNAL FUNCTION 或 CREATE MODEL 等命令的访问权限。向用户、角色或组授予对 IAM 角色的 ASSUMEROLE 权限后，该用户、角色或组可以在运行命令时代入该角色。ASSUMEROLE 权限让您可以根据需要授予对相应命令的访问权限。

只有数据库超级用户才可以授予或撤销用户、角色和组的 ASSUMEROLE 权限。超级用户始终保留 ASSUMEROLE 权限。

要为用户、角色和组启用 ASSUMEROLE 权限，超级用户需要执行以下两项操作：
+ 在集群上运行以下语句一次：

  ```
  revoke assumerole on all from public for all;
  ```
+ 向用户、角色和组授予相应命令的 ASSUMEROLE 权限。

在授予 ASSUMEROLE 权限时，您可以在 ON 子句中指定角色链接。您可以使用逗号来分隔角色链中的角色，例如 `Role1,Role2,Role3`。如果在授予 ASSUMEROLE 权限时指定了角色链接，则在执行由 ASSUMEROLE 权限授予的操作时，必须指定角色链。在执行由 ASSUMEROLE 权限授予的操作时，您无法在角色链中指定各个角色。例如，如果某个用户、角色或组被授予角色链 `Role1,Role2,Role3`，则不能仅指定 `Role1` 来执行操作。

如果用户尝试执行 COPY、UNLOAD、EXTERNAL FUNCTION 或 CREATE MODEL 操作，但尚未被授予 ASSUMEROLE 权限，则会显示类似于以下内容的消息。

```
ERROR:  User awsuser does not have ASSUMEROLE permission on IAM role "arn:aws:iam::123456789012:role/RoleA" for COPY 
```

要列出已通过 ASSUMEROLE 权限授予对 IAM 角色和命令的访问权限的用户，请参阅[HAS\$1ASSUMEROLE\$1PRIVILEGE](r_HAS_ASSUMEROLE_PRIVILEGE.md)。要列出已授予您指定的用户的 IAM 角色和命令权限，请参阅[PG\$1GET\$1IAM\$1ROLE\$1BY\$1USER](PG_GET_IAM_ROLE_BY_USER.md)。要列出已被授权访问您指定的 IAM 角色的用户、角色和组，请参阅 [PG\$1GET\$1GRANTEE\$1BY\$1IAM\$1ROLE](PG_GET_GRANTEE_BY_IAMROLE.md)。

## 有关授予机器学习权限的使用说明
<a name="r_GRANT-usage-notes-create-model"></a>

您不能直接授予或撤销与机器学习函数相关的权限。机器学习函数属于机器学习模型，其权限通过模型来控制。相反，您可以授予与机器学习模型相关的权限。以下示例演示如何向所有用户授予权限，以便运行与 `customer_churn` 模型关联的机器学习函数。

```
GRANT EXECUTE ON MODEL customer_churn TO PUBLIC;
```

还可以向用户授予对机器学习模型 `customer_churn` 的所有权限。

```
GRANT ALL on MODEL customer_churn TO ml_user;
```

如果架构中有机器学习函数，则授予与机器学习函数相关的 `EXECUTE` 权限将失败，即使该机器学习函数已通过 `GRANT EXECUTE ON MODEL` 获得 `EXECUTE` 权限。我们建议在使用 `CREATE MODEL` 命令时，通过单独的架构将机器学习函数单独保存在单独架构本身中。以下示例演示了如何执行此操作。

```
CREATE MODEL ml_schema.customer_churn
FROM customer_data
TARGET churn
FUNCTION ml_schema.customer_churn_prediction
IAM_ROLE default
SETTINGS (
 S3_BUCKET 'amzn-s3-demo-bucket'
);
```

# 示例
<a name="r_GRANT-examples"></a>

 以下示例向用户 `fred` 授予对 SALES 表的 SELECT 权限。

```
grant select on table sales to fred;
```

以下示例向用户 `fred` 授予对 QA\$1TICKIT schema 中所有表的 SELECT 权限。

```
grant select on all tables in schema qa_tickit to fred;
```

以下示例向用户组 QA\$1USERS 授予对 schema QA\$1TICKIT 的全部 schema 权限。Schema 权限包括 CREATE 和 USAGE。USAGE 向用户授予访问 schema 中对象的权限，但不授予对这些对象的 INSERT 或 SELECT 之类的权限。单独授予对每个对象的权限。

```
create group qa_users;
grant all on schema qa_tickit to group qa_users;
```

以下示例向组 QA\$1USERS 中的所有用户授予对 QA\$1TICKIT schema 中的 SALES 表的所有权限。

```
grant all on table qa_tickit.sales to group qa_users;
```

以下示例向组 QA\$1USERS 和 RO\$1USERS 中的所有用户授予对 QA\$1TICKIT 架构中的 SALES 表的所有权限。

```
grant all on table qa_tickit.sales to group qa_users, group ro_users;
```

以下示例向组 QA\$1USERS 中的所有用户授予对 QA\$1TICKIT schema 中的 SALES 表的 DROP 权限。

```
grant drop on table qa_tickit.sales to group qa_users;>
```

以下命令序列说明，具有对 schema 的访问权限并不表示授予对 schema 中的表的权限。

```
create user schema_user in group qa_users password 'Abcd1234';
create schema qa_tickit;
create table qa_tickit.test (col1 int);
grant all on schema qa_tickit to schema_user;

set session authorization schema_user;
select current_user;


current_user
--------------
schema_user
(1 row)


select count(*) from qa_tickit.test;


ERROR: permission denied for relation test [SQL State=42501]


set session authorization dw_user;
grant select on table qa_tickit.test to schema_user;
set session authorization schema_user;
select count(*) from qa_tickit.test;


count
-------
0
(1 row)
```

以下命令序列说明，具有对视图的访问权限并不意味着具有对基础表的访问权限。虽然名为 VIEW\$1USER 的用户已被授予 VIEW\$1DATE 的所有权限，但该用户无法从 DATE 表中选择数据。

```
create user view_user password 'Abcd1234';
create view view_date as select * from date;
grant all on view_date to view_user;
set session authorization view_user;
select current_user;


current_user
--------------
view_user
(1 row)


select count(*) from view_date;


count
-------
365
(1 row)


select count(*) from date;


ERROR:  permission denied for relation date
```

以下示例向用户 `cust_name` 授予对 `cust_phone` 表的 `cust_profile` 和 `user1` 列的 SELECT 权限。

```
grant select(cust_name, cust_phone) on cust_profile to user1;
```

以下示例向 `cust_name` 组授予对 `cust_phone` 和 `cust_contact_preference` 列的 SELECT 权限，并授予对 `cust_profile` 表的 `sales_group` 列的 UPDATE 权限。

```
grant select(cust_name, cust_phone), update(cust_contact_preference) on cust_profile to group sales_group;
```

下面的示例演示如何使用 ALL 关键字向 `cust_profile` 组授予对 `sales_admin` 表的三列的 SELECT 和 UPDATE 权限。

```
grant ALL(cust_name, cust_phone,cust_contact_preference) on cust_profile to group sales_admin;
```

以下示例向用户 `cust_name` 授予对 `cust_profile_vw` 视图的 `user2` 列的 SELECT 权限。

```
grant select(cust_name) on cust_profile_vw to user2;
```

## 授予数据共享访问权限的示例
<a name="r_GRANT-examples-datashare"></a>

以下示例显示了 GRANT 数据共享对特定数据库或基于数据共享创建的 schema 的使用权限。

在以下示例中，生产者端管理员向指定命名空间授予对 `salesshare` 数据共享的 USAGE 权限。

```
GRANT USAGE ON DATASHARE salesshare TO NAMESPACE '13b8833d-17c6-4f16-8fe4-1a018f5ed00d';
```

在以下示例中，使用者端管理员向 `Bob` 授予对 `sales_db` 的 USAGE 权限。

```
GRANT USAGE ON DATABASE sales_db TO Bob;
```

在以下示例中，使用者端管理员向 `Analyst_role` 角色授予对 `sales_schema` 架构的 GRANT USAGE 权限。`sales_schema` 是一个指向 sales\$1db 的外部架构。

```
GRANT USAGE ON SCHEMA sales_schema TO ROLE Analyst_role;
```

此时，`Bob` 和 `Analyst_role` 可以访问 `sales_schema` 和 `sales_db` 中的所有数据库对象。

以下示例显示了对共享数据库中的对象授予额外的对象级权限。只有在用于创建共享数据库的 CREATE DATABASE 命令使用了 WITH PERMISSIONS 子句时，才需要这些额外的权限。如果 CREATE DATABASE 命令未使用 WITH PERMISSIONS，则在共享数据库上授予 USAGE 权限将授予对该数据库中所有对象的完全访问权限。

```
GRANT SELECT ON sales_db.sales_schema.tickit_sales_redshift to Bob;
```

## 授予限定范围权限的示例
<a name="r_GRANT-examples-scoped"></a>

以下示例将 `Sales_db` 数据库中所有当前和将来架构的使用权限授予给 `Sales` 角色。

```
GRANT USAGE FOR SCHEMAS IN DATABASE Sales_db TO ROLE Sales;
```

以下示例向用户 `alice` 授予对 `Sales_db` 数据库中所有当前和未来表的 SELECT 权限，同时还向 `alice` 授予权限以向其他用户授予对 `Sales_db` 中表的限定范围权限。

```
GRANT SELECT FOR TABLES IN DATABASE Sales_db TO alice WITH GRANT OPTION;
```

以下示例向用户 `bob` 授予对 `Sales_schema` 架构中函数的 EXECUTE 权限。

```
GRANT EXECUTE FOR FUNCTIONS IN SCHEMA Sales_schema TO bob;
```

以下示例向 `Sales` 角色授予对 `ShareDb` 数据库 `ShareSchema` 架构中所有表的所有权限。指定架构时，您可以使用由两部分组成的格式 `database.schema` 指定架构的数据库。

```
GRANT ALL FOR TABLES IN SCHEMA ShareDb.ShareSchema TO ROLE Sales;
```

下面的示例与前一个示例相同。您可以使用 `DATABASE` 关键字而不是使用由两部分组成的格式来指定数据库。

```
GRANT ALL FOR TABLES IN SCHEMA ShareSchema DATABASE ShareDb TO ROLE Sales;
```

## 授予 ASSUMEROLE 权限的示例
<a name="r_GRANT-examples-assumerole"></a>

下面是授予 ASSUMEROLE 权限的示例。

以下示例显示了 REVOKE 语句，超级用户可以在集群上运行一次该语句，以便为用户和组启用 ASSUMEROLE 权限。然后，超级用户向用户和组授予相应命令的 ASSUMEROLE 权限。有关为用户和组启用 ASSUMEROLE 权限的信息，请参阅[有关授予 ASSUMEROLE 权限的使用说明](r_GRANT-usage-notes.md#r_GRANT-usage-notes-assumerole)。

```
revoke assumerole on all from public for all;
```

以下示例向用户 `reg_user1` 授予 IAM 角色 `Redshift-S3-Read` 的 ASSUMEROLE 权限来执行 COPY 操作。

```
grant assumerole on 'arn:aws:iam::123456789012:role/Redshift-S3-Read'
to reg_user1 for copy;
```

以下示例向用户 `reg_user1` 授予 IAM 角色链 `RoleA`、`RoleB` 的 ASSUMEROLE 权限来执行 UNLOAD 操作。

```
grant assumerole
on 'arn:aws:iam::123456789012:role/RoleA,arn:aws:iam::210987654321:role/RoleB'
to reg_user1
for unload;
```

以下是使用 IAM 角色链 `RoleA`、`RoleB` 执行 UNLOAD 命令的示例。

```
unload ('select * from venue limit 10')
to 's3://companyb/redshift/venue_pipe_'
iam_role 'arn:aws:iam::123456789012:role/RoleA,arn:aws:iam::210987654321:role/RoleB';
```

以下示例向用户 `reg_user1` 授予 IAM 角色 `Redshift-Exfunc` 的 ASSUMEROLE 权限来创建外部函数。

```
grant assumerole on 'arn:aws:iam::123456789012:role/Redshift-Exfunc'
to reg_user1 for external function;
```

以下示例向用户 `reg_user1` 授予 IAM 角色 `Redshift-model` 的 ASSUMEROLE 权限来创建机器学习模型。

```
grant assumerole on 'arn:aws:iam::123456789012:role/Redshift-ML'
to reg_user1 for create model;
```

## 授予 ROLE 权限的示例
<a name="r_GRANT-examples-role"></a>

下面的示例将向 user1 授予 sample\$1role1。

```
CREATE ROLE sample_role1;
GRANT ROLE sample_role1 TO user1;
```

以下示例使用 WITH ADMIN OPTION 将 sample\$1role1 授予 user1，为用户 1 设置当前会话，而 user1 将 sample\$1role1 授予 user2。

```
GRANT ROLE sample_role1 TO user1 WITH ADMIN OPTION;
SET SESSION AUTHORIZATION user1;
GRANT ROLE sample_role1 TO user2;
```

下面的示例将向 sample\$1role2 授予 sample\$1role1。

```
GRANT ROLE sample_role1 TO ROLE sample_role2;
```

下面的示例将向 sample\$1role3 和 sample\$1role4 授予 sample\$1role2。然后尝试将 sample\$1role3 授予 sample\$1role1。

```
GRANT ROLE sample_role2 TO ROLE sample_role3;
GRANT ROLE sample_role3 TO ROLE sample_role2;
ERROR: cannot grant this role, a circular dependency was detected between these roles
```

下面的示例将向 sample\$1role1 授予 CREATE USER 系统权限。

```
GRANT CREATE USER TO ROLE sample_role1;
```

下面的示例将向 user1 授予系统定义角色 `sys:dba`。

```
GRANT ROLE sys:dba TO user1;
```

下面的示例尝试将循环依赖关系中的 sample\$1role3 授予 sample\$1role2。

```
CREATE ROLE sample_role3;
GRANT ROLE sample_role2 TO ROLE sample_role3;
GRANT ROLE sample_role3 TO ROLE sample_role2; -- fail
ERROR:  cannot grant this role, a circular dependency was detected between these roles
```

# INSERT
<a name="r_INSERT_30"></a>

**Topics**
+ [语法](#r_INSERT_30-synopsis)
+ [参数](#r_INSERT_30-parameters)
+ [使用说明](#r_INSERT_30_usage_notes)
+ [INSERT 示例](c_Examples_of_INSERT_30.md)

将新行插入到表中。您可以使用 VALUES 语法插入单行，使用 VALUES 语法插入多行，或者插入查询结果所定义的一行或多行 (INSERT INTO...SELECT)。

**注意**  
我们强烈建议您使用 [COPY](r_COPY.md) 命令来加载大量数据。使用单个 INSERT 语句填充表可能过于缓慢。此外，如果您的数据在其他 Amazon Redshift 数据库表中已经存在，请使用 INSERT INTO SELECT 或 [CREATE TABLE AS](r_CREATE_TABLE_AS.md) 来提高性能。有关使用 COPY 命令加载表的更多信息，请参阅[在 Amazon Redshift 中加载数据](t_Loading_data.md)。

**注意**  
单个 SQL 语句的最大大小为 16MB。

## 语法
<a name="r_INSERT_30-synopsis"></a>

```
INSERT INTO table_name [ ( column [, ...] ) ]
{DEFAULT VALUES |
VALUES ( { expression | DEFAULT } [, ...] )
[, ( { expression | DEFAULT } [, ...] )
[, ...] ] |
query }
```

## 参数
<a name="r_INSERT_30-parameters"></a>

 *table\$1name*   
一个临时或永久表。只有表的所有者或对表具有 INSERT 权限的用户才能插入行。如果您使用 *query* 子句插入行，必须对查询中指定的表拥有 SELECT 权限。  
使用 INSERT（外部表）可将 SELECT 查询的结果插入到外部目录中的现有表中。有关更多信息，请参阅 [INSERT（外部表）](r_INSERT_external_table.md)。

 *column*   
您可以将值插入到表的一个或多个列中。您可以按任意顺序列出目标列名。如果不指定列的列表，则要插入的值必须按照在 CREATE TABLE 语句中声明的顺序对应于表列。如果要插入的值数小于表中的列数，则将加载前 *n* 列。  
对于在 INSERT 语句中未列出（隐式或显式）的任何列，声明的默认值或 null 值将被加载到这些列。

DEFAULT VALUES   
如果在创建表时，已向表中的列分配默认值，则可使用这些关键字插入完全包含默认值的行。如果有任何列不具有默认值，则会向这些列插入 null。如果任何列被声明为 NOT NULL，则 INSERT 语句会返回错误。

VALUES   
使用此关键字可插入一行或多行，每一行包括一个或多个值。每一行的 VALUES 列表必须与列的列表对应。要插入多个行，请在每个表达式列表之间使用逗号分隔符。不要重复使用 VALUES 关键字。多行 INSERT 语句的所有 VALUES 列表必须包含相同数量的值。

 *expression*   
单个值，或计算结果为单个值的表达式。每个值必须与该值所插入到的列的数据类型相兼容。对于其数据类型与列的已声明数据类型不匹配的值，会尽可能地自动转换为兼容的数据类型。例如：  
+ 一个数字值 `1.1` 将以 `1` 值插入到 INT 列中。
+ 一个数字值 `100.8976` 将以 `100.90` 值插入到 DEC(5,2) 列中。
您可以通过在表达式中包含类型强制转换语法，显式地将值转换成某个兼容的数据类型。例如，表 T1 中的列 COL1 是 CHAR(3) 列：  

```
insert into t1(col1) values('Incomplete'::char(3));
```
此语句将值 `Inc` 插入到列中。  
对于单行 INSERT VALUES 语句，可以使用标量子查询作为表达式。子查询的结果将插入到适当的列中。  
对于多行 INSERT VALUES 语句，不支持将子查询用作表达式。

DEFAULT   
使用此关键字可以按照在创建表时定义的方式，为列插入默认值。如果列不存在默认值，则插入 null 值。对于具有 NOT NULL 约束的列，如果没有在 CREATE TABLE 语句中明确为该列分配默认值，则不能将默认值插入到该列中。

 *query*   
通过定义任何查询，将一行或多行插入到表中。查询生成的所有行都将插入到表中。查询必须返回与表列相兼容的列的列表，不过列名称不一定要匹配。

## 使用说明
<a name="r_INSERT_30_usage_notes"></a>

**注意**  
我们强烈建议您使用 [COPY](r_COPY.md) 命令来加载大量数据。使用单个 INSERT 语句填充表可能过于缓慢。此外，如果您的数据在其他 Amazon Redshift 数据库表中已经存在，请使用 INSERT INTO SELECT 或 [CREATE TABLE AS](r_CREATE_TABLE_AS.md) 来提高性能。有关使用 COPY 命令加载表的更多信息，请参阅[在 Amazon Redshift 中加载数据](t_Loading_data.md)。

所插入值的数据格式必须与 CREATE TABLE 定义指定的数据格式匹配。

 在表中插入大量新行后：
+ 对表执行 Vacuum 操作，以回收存储空间并对行重新排序。
+ 分析表以更新查询计划程序的统计数据。

如果在将值插入到 DECIMAL 列时，这些值超过了指定的小数位数，则会根据需要对加载的值向上取整。例如，如果将值 `20.259` 插入到 DECIMAL(8,2) 列中，则存储的值是 `20.26`。

您可以插入到 GENERATED BY DEFAULT AS IDENTITY 列。您可以使用您提供的值来更新定义为 GENERATED BY DEFAULT AS IDENTITY 的列。有关更多信息，请参阅 [GENERATED BY DEFAULT AS IDENTITY](r_CREATE_TABLE_NEW.md#identity-generated-bydefault-clause)。

# INSERT 示例
<a name="c_Examples_of_INSERT_30"></a>

TICKIT 数据库中的 CATEGORY 表包含以下行：

```
 catid | catgroup |  catname  |                  catdesc
-------+----------+-----------+--------------------------------------------
     1 | Sports   | MLB       | Major League Baseball
     2 | Sports   | NHL       | National Hockey League
     3 | Sports   | NFL       | National Football League
     4 | Sports   | NBA       | National Basketball Association
     5 | Sports   | MLS       | Major League Soccer
     6 | Shows    | Musicals  | Musical theatre
     7 | Shows    | Plays     | All non-musical theatre
     8 | Shows    | Opera     | All opera and light opera
     9 | Concerts | Pop       | All rock and pop music concerts
    10 | Concerts | Jazz      | All jazz singers and bands
    11 | Concerts | Classical | All symphony, concerto, and choir concerts
(11 rows)
```

 使用与 CATEGORY 表类似的 schema 来创建 CATEGORY\$1STAGE 表，但为列定义默认值：

```
create table category_stage
(catid smallint default 0,
catgroup varchar(10) default 'General',
catname varchar(10) default 'General',
catdesc varchar(50) default 'General');
```

下面的 INSERT 语句从 CATEGORY 表中选择所有行并将它们插入 CATEGORY\$1STAGE 表。

```
insert into category_stage
(select * from category);
```

查询两旁的括号是可选的。

此命令在 CATEGORY\$1STAGE 表中插入新行，并按顺序为每列指定值：

```
insert into category_stage values
(12, 'Concerts', 'Comedy', 'All stand-up comedy performances');
```

您还可以插入结合使用特定值和默认值的新行：

```
insert into category_stage values
(13, 'Concerts', 'Other', default);
```

运行以下查询以返回插入的行：

```
select * from category_stage
where catid in(12,13) order by 1;

 catid | catgroup | catname |             catdesc
-------+----------+---------+----------------------------------
    12 | Concerts | Comedy  | All stand-up comedy performances
    13 | Concerts | Other   | General
(2 rows)
```

下面的示例说明了一些多行 INSERT VALUES 语句。第一个示例为两行插入特定的 CATID 值，并为这两行中的其他列插入默认值。

```
insert into category_stage values
(14, default, default, default),
(15, default, default, default);

select * from category_stage where catid in(14,15) order by 1;
 catid | catgroup | catname | catdesc
-------+----------+---------+---------
    14 | General  | General | General
    15 | General  | General | General
(2 rows)
```

下一个示例插入包含特定值和默认值的各种组合的三行：

```
insert into category_stage values
(default, default, default, default),
(20, default, 'Country', default),
(21, 'Concerts', 'Rock', default);

select * from category_stage where catid in(0,20,21) order by 1;
 catid | catgroup | catname | catdesc
-------+----------+---------+---------
     0 | General  | General | General
    20 | General  | Country | General
    21 | Concerts | Rock    | General
(3 rows)
```

本示例中的第一组 VALUES 生成的结果与为单行 INSERT 语句指定 DEFAULT VALUES 所生成的结果相同。

以下示例说明当表具有 IDENTITY 列时的 INSERT 行为。首先，创建 CATEGORY 表的新版本，然后将行从 CATEGORY 插入到新表：

```
create table category_ident
(catid int identity not null,
catgroup varchar(10) default 'General',
catname varchar(10) default 'General',
catdesc varchar(50) default 'General');


insert into category_ident(catgroup,catname,catdesc)
select catgroup,catname,catdesc from category;
```

请注意，您不能将特定的整数值插入到 CATID IDENTITY 列。IDENTITY 列值会自动生成。

以下示例说明了不能在多行 INSERT VALUES 语句中将子查询用作表达式：

```
insert into category(catid) values
((select max(catid)+1 from category)),
((select max(catid)+2 from category));

ERROR: can't use subqueries in multi-row VALUES
```

以下示例显示了在临时表中插入的内容，临时表中使用 `WITH SELECT` 子句填充了 `venue` 表中的数据。有关 `venue` 表的更多信息，请参阅 [示例数据库](c_sampledb.md)。

首先，创建临时表 `#venuetemp`。

```
CREATE TABLE #venuetemp AS SELECT * FROM venue;
```

列出 `#venuetemp` 表中的行。

```
SELECT * FROM #venuetemp ORDER BY venueid;
         
venueid | venuename                | venuecity  | venuestate| venueseats
--------+--------------------------+------------+-----------+------------
1        Toyota Park                Bridgeview   IL          0	
2        Columbus Crew Stadium      Columbus     OH          0	
3        RFK Stadium                Washington   DC          0	
4        CommunityAmerica Ballpark  Kansas City  KS          0	
5        Gillette Stadium           Foxborough   MA          68756	
...
```

使用 `WITH SELECT` 子句在 `#venuetemp` 表中插入 10 个重复的行。

```
INSERT INTO #venuetemp (WITH venuecopy AS (SELECT * FROM venue) SELECT * FROM venuecopy ORDER BY 1 LIMIT 10);
```

列出 `#venuetemp` 表中的行。

```
SELECT * FROM #venuetemp ORDER BY venueid;
         
venueid | venuename                | venuecity  | venuestate| venueseats
--------+--------------------------+------------+-----------+------------
1        Toyota Park                Bridgeview   IL          0	
1        Toyota Park                Bridgeview   IL          0	
2        Columbus Crew Stadium      Columbus     OH          0	
2        Columbus Crew Stadium      Columbus     OH          0	
3        RFK Stadium                Washington   DC          0
3        RFK Stadium                Washington   DC          0	
4        CommunityAmerica Ballpark  Kansas City  KS          0	
4        CommunityAmerica Ballpark  Kansas City  KS          0	
5        Gillette Stadium           Foxborough   MA          68756
5        Gillette Stadium           Foxborough   MA          68756
...
```

# INSERT（外部表）
<a name="r_INSERT_external_table"></a>

将 SELECT 查询的结果插入（如 AWS Glue、AWS Lake Formation 或 Apache Hive 元存储的）外部目录上的现有外部表中。使用与用于 CREATE EXTERNAL SCHEMA 命令相同的 AWS Identity and Access Management (IAM) 角色与外部目录和 Amazon S3 进行交互。

对于未分区的表，INSERT（外部表）命令根据指定的表属性和文件格式将数据写入在表中定义的 Amazon S3 位置。

对于已分区的表，INSERT（外部表）根据表中指定的分区键将数据写入 Amazon S3 位置。在 INSERT 操作完成后，它还会自动在外部目录中注册新分区。

您不能在事务数据块 (BEGIN ... END) 中运行 INSERT（外部表）。有关事务的更多信息，请参阅 [Amazon Redshift 中的隔离级别](c_serial_isolation.md)。

## 语法
<a name="r_INSERT_external_table-synopsis"></a>

```
INSERT INTO external_schema.table_name
{ select_statement }
```

## 参数
<a name="r_INSERT_external_table-parameters"></a>

 *external\$1schema.table\$1name*   
现有外部架构和要插入到的目标外部表的名称。

 *select\$1statement*   
通过定义任何查询将一行或多行插入外部表的语句。查询生成的所有行都将根据表定义以文本或 Parquet 格式写入到 Amazon S3 。查询必须返回与外部表中的列数据类型兼容的列列表。但是，列名称不必匹配。

## 使用说明
<a name="r_INSERT_external_table_usage_notes"></a>

SELECT 查询中的列数必须与数据列和分区列的总和相同。每个数据列的位置和数据类型必须与外部表的位置和数据类型相匹配。分区列的位置必须位于 SELECT 查询的末尾，与在 CREATE EXTERNAL TABLE 命令中定义它们的顺序相同。列名称不必匹配。

在某些情况下，您可能需要对 AWS Glue 数据目录或 Hive 元存储运行 INSERT（外部表）命令。在 AWS Glue 的情况下，用于创建外部架构的 IAM 角色必须对 Amazon S3 和 AWS Glue 具有读取和写入权限。如果您使用 AWS Lake Formation 目录，则此 IAM 角色将成为新 Lake Formation 表的拥有者。此 IAM 角色必须至少具有以下权限：
+ 对外部表的 SELECT、INSERT、UPDATE 权限
+ 外部表的 Amazon S3 路径上的数据位置权限

为确保文件名是唯一的，Amazon Redshift 预设情况下对上载到 Amazon S3 的每个文件的名称使用以下格式。

`<date>_<time>_<microseconds>_<query_id>_<slice-number>_part_<part-number>.<format>`.

示例是 `20200303_004509_810669_1007_0001_part_00.parquet`。

运行 INSERT（外部表）命令时，请考虑以下事项：
+ 不支持非 PARQUET 或 TEXTFILE 格式的外部表。
+ 此命令支持现有的表属性，例如 'write.parallel'、'write.maxfilesize.mb'、'compression\$1type’ 和 'serialization.null.format'。要更新这些值，请运行 ALTER TABLE SET TABLE PROPERTIES 命令。
+ 'numRows’ 表属性会在 INSERT 操作结束时自动更新。如果表属性不是由 CREATE EXTERNAL TABLE AS 操作创建的，则必须已经定义或添加到表中。
+ 外部 SELECT 查询不支持 LIMIT 子句。请改为使用嵌套 LIMIT 子句。
+ 您可以使用 [STL\$1UNLOAD\$1LOG](r_STL_UNLOAD_LOG.md) 表跟踪每个 INSERT（外部表）操作写入 Amazon S3 的文件。
+ Amazon Redshift 仅支持 Amazon S3 标准加密用于 INSERT（外部表）。

## INSERT（外部表）示例
<a name="c_Examples_of_INSERT_external_table"></a>

以下示例将 SELECT 语句的结果插入到外部表中。

```
INSERT INTO spectrum.lineitem
SELECT * FROM local_lineitem;
```

以下示例使用静态分区将 SELECT 语句的结果插入到已分区的外部表中。分区列在 SELECT 语句中是硬编码的。分区列必须位于查询的末尾。

```
INSERT INTO spectrum.customer
SELECT name, age, gender, 'May', 28 FROM local_customer;
```

以下示例使用动态分区将 SELECT 语句的结果插入到已分区的外部表中。分区列不是硬编码的。数据自动添加到现有分区文件夹中，或者，如果添加了新分区，则会将数据自动添加到新文件夹中。

```
INSERT INTO spectrum.customer
SELECT name, age, gender, month, day FROM local_customer;
```

# LOCK
<a name="r_LOCK"></a>

限制对数据库表的访问。此命令只在事务块内部运行时才有意义。

LOCK 命令在“ACCESS EXCLUSIVE”模式下获取表级别的锁定；如果需要，会等待所有冲突的锁定释放。通过这种方式明确地锁定表时，会导致从其他事务或会话尝试对表执行的读取和写入操作等待。当一个用户明确地锁定表时，会阻止另一个用户从该表中选择数据或在该表中加载数据。当包含 LOCK 命令的事务完成后，会释放锁定。

引用表的命令会隐式地获取限制性较低的表锁定，例如写入操作。例如，如果某个用户尝试从表中读取数据，而另一个用户正在更新该表，那么读取的数据将是已提交的数据的快照。（在某些情况下，如果查询违反了可序列化隔离规则，则将停止。） 请参阅 [管理并发写入操作](c_Concurrent_writes.md)。

一些 DDL 操作（例如 DROP TABLE 和 TRUNCATE）会创建独占锁定。这些操作会阻止读取数据。

如果发生锁定冲突，Amazon Redshift 会显示错误消息，对启动冲突事务的用户发出提示。收到锁定冲突的事务将会停止。每次发生锁定冲突时，Amazon Redshift 会将一个条目写入到 [STL\$1TR\$1CONFLICT](r_STL_TR_CONFLICT.md) 表。

## 语法
<a name="section_r_LOCK-synopsis"></a>

```
LOCK [ TABLE ] table_name [, ...]
```

## 参数
<a name="parameters"></a>

TABLE   
可选关键字。

 *table\$1name*   
要锁定的表的名称。通过使用逗号分隔的表名列表可以锁定多个表。您不能锁定视图。

## 示例
<a name="example2"></a>

```
begin;

lock event, sales;

...
```

# MERGE
<a name="r_MERGE"></a>

按条件将源表中的行合并到目标表中。通常这只能通过单独使用多个插入、更新或删除语句来实现。有关 MERGE 允许您合并的操作的更多信息，请参阅 [UPDATE](https://docs.aws.amazon.com/redshift/latest/dg/r_UPDATE.html)、[DELETE](https://docs.aws.amazon.com/redshift/latest/dg/r_DELETE.html) 和 [INSERT](https://docs.aws.amazon.com/redshift/latest/dg/r_INSERT_30.html)。

## 语法
<a name="r_MERGE-synopsis"></a>

```
MERGE INTO target_table 
USING source_table [ [ AS ] alias ] 
ON match_condition 
[ WHEN MATCHED THEN { UPDATE SET col_name = { expr } [,...] | DELETE }
WHEN NOT MATCHED THEN INSERT [ ( col_name [,...] ) ] VALUES ( { expr } [, ...] ) |
REMOVE DUPLICATES ]
```

## 参数
<a name="r_MERGE-parameters"></a>

 *target\$1table*  
MERGE 语句合并到的临时表或永久表。

 *source\$1table*  
提供要合并到 *target\$1table* 的行的临时表或永久表。*source\$1table* 也可以是 Spectrum 表。

 *别名*  
*source\$1table* 的临时备用名称。  
此参数为可选的。在*别名*前加上 AS 也是可选的。

 *match\$1condition*  
在源表列和目标表列之间指定同等的谓词，用于确定 *source\$1table* 中的行是否可以与 *target\$1table* 中的行匹配。如果满足条件，MERGE 会对该行运行 *matched\$1clause*。否则 MERGE 会为该行运行 *not\$1matched\$1clause*。

WHEN MATCHED  
 指定当源行和目标行之间的匹配条件计算结果为 True 时要运行的操作。您可以指定 UPDATE 操作或 DELETE 操作。

UPDATE  
 更新 *target\$1table* 中的匹配行。仅更新您在 *col\$1name* 中指定的值。

DELETE  
 删除 *target\$1table* 中的匹配行。

WHEN NOT MATCHED  
 指定当匹配条件计算结果为 False 或 Unknown 时要运行的操作。只能为此子句指定 INSERT 插入操作。

INSERT  
 根据 *match\$1condition*，从 *source\$1table* 插入与 *target\$1table* 中的任何行都不匹配的 *target\$1table* 行。可以按任意顺序列出目标 *col\$1name*。如果您不提供任何 *col\$1name* 值，则默认顺序是表中所有列的声明顺序。

 *col\$1name*  
要修改的一个或多个列名。指定目标列时不包括表名。

 *\$1 expr*  
定义新 *col\$1name* 值的表达式。

 REMOVE DUPLICATES  
指定 MERGE 命令在简化模式下运行。简化模式具有以下要求：  
+  *target\$1table* 和 *source\$1table* 必须具有相同数量的列、兼容的列类型以及相同的列顺序。
+  在 MERGE 命令中省略 WHEN 子句以及 UPDATE 和 INSERT 子句。
+  在 MERGE 命令中使用 REMOVE DUPLICATES 子句。
在简化模式下，MERGE 执行以下操作：  
+  *target\$1table* 中与 *source\$1table* 中存在匹配项的行将更新为与 *source\$1table* 中的值相匹配。
+  *source\$1table* 中与 *target\$1table* 中不存在匹配项的行将插入到 *target\$1table* 中。
+  当 *target\$1table* 中的多个行与 *source\$1table* 中的同一行匹配时，将删除重复的行。Amazon Redshift 保留一行并对其进行更新。与 *source\$1table* 中的行不匹配的重复行将保持不变。
与使用 WHEN MATCHED 和 WHEN NOT MATCHED 相比，使用 REMOVE DUPLICATES 可获得更好的性能。如果 *target\$1table* 和 *source\$1table* 兼容，并且您不需要在 *target\$1table* 中保留重复行，我们建议您使用 REMOVE DUPLICATES。

## 使用说明
<a name="r_MERGE_usage_notes"></a>
+ 要运行 MERGE 语句，您必须是 *source\$1table* 和 *target\$1table* 的所有者，或者具有这些表的 SELECT 权限。此外，您必须拥有 *target\$1table* 的 UPDATE、DELETE 和 INSERT 权限，具体取决于 MERGE 语句中包括的操作。
+  *target\$1table* 不能是系统表、目录表或外部表。
+  *source\$1table* 和 *target\$1table* 不能是同一个表。
+  不能在 MERGE 语句中使用 WITH 子句。
+  *source\$1table* 中的行不能匹配 *target\$1table* 中的多行。

  考虑以下示例：

  ```
  CREATE TABLE target (id INT, name CHAR(10));
  CREATE TABLE source (id INT, name CHAR(10));
  
  INSERT INTO target VALUES (1, 'Bob'), (2, 'John');
  INSERT INTO source VALUES (1, 'Tony'), (1, 'Alice'), (3, 'Bill');
  
  MERGE INTO target USING source ON target.id = source.id
  WHEN MATCHED THEN UPDATE SET id = source.id, name = source.name
  WHEN NOT MATCHED THEN INSERT VALUES (source.id, source.name);
  ERROR: Found multiple matches to update the same tuple.
  
  MERGE INTO target USING source ON target.id = source.id
  WHEN MATCHED THEN DELETE
  WHEN NOT MATCHED THEN INSERT VALUES (source.id, source.name);
  ERROR: Found multiple matches to update the same tuple.
  ```

  这两个 MERGE 语句中的操作均失败，因为 `source` 表中有多个行具有 ID 值 `1`。
+  *match\$1condition* 和 *expr* 不能部分引用 SUPER 类型列。例如，如果您的 SUPER 类型对象是数组或结构，则不能为 *match\$1condition* 或 *expr* 使用该列的个别元素，但您可以使用整列。

  考虑以下示例：

  ```
  CREATE TABLE IF NOT EXISTS target (key INT, value SUPER);
  CREATE TABLE IF NOT EXISTS source (key INT, value SUPER);
  
  INSERT INTO target VALUES (1, JSON_PARSE('{"key": 88}'));
  INSERT INTO source VALUES (1, ARRAY(1, 'John')), (2, ARRAY(2, 'Bill'));
  
  MERGE INTO target USING source ON target.key = source.key
  WHEN matched THEN UPDATE SET value = source.value[0]
  WHEN NOT matched THEN INSERT VALUES (source.key, source.value[0]);
  ERROR: Partial reference of SUPER column is not supported in MERGE statement.
  ```

  有关 SUPER 类型的更多信息，请参阅 [SUPER 类型](https://docs.aws.amazon.com/redshift/latest/dg/r_SUPER_type.html)。
+ 如果 *source\$1table* 很大，则将 *target\$1table* 和 *source\$1table* 中的联接列定义为分配键可以提高性能。
+ 要使用 REMOVE DUPLICATES 子句，您需要对 *target\$1table* 拥有 SELECT、INSERT 和 DELETE 权限。
+  *source\$1table* 可以是视图或子查询。以下是 MERGE 语句的示例，其中 *source\$1table* 是一个用于移除重复行的子查询。

  ```
  MERGE INTO target
  USING (SELECT id, name FROM source GROUP BY 1, 2) as my_source
  ON target.id = my_source.id
  WHEN MATCHED THEN UPDATE SET id = my_source.id, name = my_source.name
  WHEN NOT MATCHED THEN INSERT VALUES (my_source.id, my_source.name);
  ```
+ 目标不能是同一 MERGE 语句的任何子查询的数据来源。例如，以下 SQL 命令返回与错误：Merge 语句中的源视图/子查询无法引用目标表类似的错误，因为子查询引用的是 `target` 而不是 `source`。

  ```
  MERGE INTO target
  USING (SELECT id, name FROM target GROUP BY 1, 2) as my_source
  ON target.id = my_source.id
  WHEN MATCHED THEN UPDATE SET id = my_source.id, name = my_source.name
  WHEN NOT MATCHED THEN INSERT VALUES (my_source.id, my_source.name);
  ```

## 示例
<a name="sub-examples-merge"></a>

以下示例创建了两个表，然后对它们运行 MERGE 操作，更新目标表中的匹配行并插入不匹配的行。然后，它将另一个值插入源表并运行另一个 MERGE 操作，这次是删除匹配行并从源表插入新行。

首先创建并填充源表和目标表。

```
CREATE TABLE target (id INT, name CHAR(10));
CREATE TABLE source (id INT, name CHAR(10));

INSERT INTO target VALUES (101, 'Bob'), (102, 'John'), (103, 'Susan');
INSERT INTO source VALUES (102, 'Tony'), (103, 'Alice'), (104, 'Bill');

SELECT * FROM target;
 id  |    name
-----+------------
 101 | Bob
 102 | John
 103 | Susan
(3 rows)

SELECT * FROM source;
 id  |    name
-----+------------
 102 | Tony
 103 | Alice
 104 | Bill
(3 rows)
```

接下来，将源表合并到目标表，用匹配行更新目标表，并插入源表中没有匹配的行。

```
MERGE INTO target USING source ON target.id = source.id
WHEN MATCHED THEN UPDATE SET id = source.id, name = source.name
WHEN NOT MATCHED THEN INSERT VALUES (source.id, source.name);

SELECT * FROM target;
 id  |    name
-----+------------
 101 | Bob
 102 | Tony
 103 | Alice
 104 | Bill
(4 rows)
```

请注意，ID 值为 102 和 103 的行已更新，以匹配目标表中的名称值。此外，在目标表中插入一个 ID 值为 104 且名称值为 Bill 的新行。

接下来，在源表中插入新行。

```
INSERT INTO source VALUES (105, 'David');

SELECT * FROM source;
 id  |    name
-----+------------
 102 | Tony
 103 | Alice
 104 | Bill
 105 | David
(4 rows)
```

最后，运行合并操作，删除目标表中的匹配行，然后插入不匹配的行。

```
MERGE INTO target USING source ON target.id = source.id
WHEN MATCHED THEN DELETE
WHEN NOT MATCHED THEN INSERT VALUES (source.id, source.name);

SELECT * FROM target;
 id  |    name
-----+------------
 101 | Bob
 105 | David
(2 rows)
```

从目标表中删除 ID 值为 102、103 和 104 的行，并在目标表中插入 ID 值为 105 且名称值为 David 的新行。

以下示例显示了使用 REMOVE DUPLICATES 子句的 MERGE 命令的简化语法。

```
CREATE TABLE target (id INT, name CHAR(10));
CREATE TABLE source (id INT, name CHAR(10));

INSERT INTO target VALUES (30, 'Tony'), (11, 'Alice'), (23, 'Bill');
INSERT INTO source VALUES (23, 'David'), (22, 'Clarence');

MERGE INTO target USING source ON target.id = source.id REMOVE DUPLICATES;

SELECT * FROM target;
id | name
---+------------
30 | Tony
11 | Alice
23 | David
22 | Clarence
(4 rows)
```

以下示例显示了使用 REMOVE DUPLICATES 子句的 MERGE 命令的简化语法，如果重复行在 *source\$1table* 中有匹配的行，则从 *target\$1table* 中移除重复行。

```
CREATE TABLE target (id INT, name CHAR(10));
CREATE TABLE source (id INT, name CHAR(10));

INSERT INTO target VALUES (30, 'Tony'), (30, 'Daisy'), (11, 'Alice'), (23, 'Bill'), (23, 'Nikki');
INSERT INTO source VALUES (23, 'David'), (22, 'Clarence');

MERGE INTO target USING source ON target.id = source.id REMOVE DUPLICATES;

SELECT * FROM target;
id | name
---+------------
30 | Tony
30 | Daisy
11 | Alice
23 | David
22 | Clarence
(5 rows)
```

MERGE 运行后，*target\$1table* 中只有一行的 ID 值为 23。由于 *source\$1table* 中没有 ID 值为 30 的行，因此 ID 值为 30 的两个重复行仍保留在 *target\$1table* 中。

## 另请参阅
<a name="r_MERGE-see-also"></a>

 [INSERT](r_INSERT_30.md), [UPDATE](r_UPDATE.md), [DELETE](r_DELETE.md) 

# PREPARE
<a name="r_PREPARE"></a>

准备语句以便执行。

PREPARE 会创建一个预编译语句。在运行 PREPARE 语句时，会对指定的语句（SELECT、INSERT、UPDATE 或 DELETE）进行解析、重写和计划。为预编译语句发出 EXECUTE 命令时，Amazon Redshift 可能会选择修改查询执行计划（以便根据指定的参数值来提高性能），然后再执行预编译语句。

## 语法
<a name="r_PREPARE-synopsis"></a>

```
PREPARE plan_name [ (datatype [, ...] ) ] AS statement
```

## 参数
<a name="r_PREPARE-parameters"></a>

 *plan\$1name*   
为此特定预编译语句指定的任意名称。它在单个会话中必须是唯一的，随后用于执行或取消分配先前预编译的语句。

 *datatype*   
预编译语句的参数的数据类型。要在已准备的语句自身中引用参数，请使用 \$11、\$12 等，最多可达 \$132767。

 *statement *   
任意 SELECT、INSERT、UPDATE 或 DELETE 语句。

## 使用说明
<a name="r_PREPARE_usage_notes"></a>

预编译语句可以接受参数和值，它们在执行语句时将会被取代。要在预编译语句中包含参数，请在 PREPARE 语句中提供数据类型的列表；并在要预编译的语句自身中，通过使用 \$11, \$12, ... 表示法来按位置引用参数。参数的最大数量为 32767。执行该语句时，会在 EXECUTE 语句中为这些参数指定实际值。有关更多信息，请参阅 [EXECUTE](r_EXECUTE.md)。

预编译语句只在当前会话的持续时间内有效。当会话结束时，预编译语句将被丢弃，因此必须重新创建该语句才能再次使用。这也意味着一个预编译语句不能同时由多个数据库客户端使用；不过，每个客户端可以创建自己的预编译语句加以使用。可以使用 DEALLOCATE 命令手动删除预编译语句。

当一个会话用于执行大量类似的语句时，预编译语句能够发挥最大的性能优势。正如上文所述，对于预编译语句的每次新执行，Amazon Redshift 可能会根据指定的参数值，再次修改查询执行计划来提高性能。要检查 Amazon Redshift 为任何特定 EXECUTE 语句选择的查询执行计划，请使用 [EXPLAIN](r_EXPLAIN.md) 命令。

有关查询计划的更多信息以及 Amazon Redshift 为查询优化收集的统计数据，请参阅 [ANALYZE](r_ANALYZE.md) 命令。

## 示例
<a name="sub-examples-prepare"></a>

创建一个临时表，准备 INSERT 语句并执行该语句：

```
DROP TABLE IF EXISTS prep1;
CREATE TABLE prep1 (c1 int, c2 char(20));
PREPARE prep_insert_plan (int, char)
AS insert into prep1 values ($1, $2);
EXECUTE prep_insert_plan (1, 'one');
EXECUTE prep_insert_plan (2, 'two');
EXECUTE prep_insert_plan (3, 'three');
DEALLOCATE prep_insert_plan;
```

准备 SELECT 语句并执行该语句：

```
PREPARE prep_select_plan (int)
AS select * from prep1 where c1 = $1;
EXECUTE prep_select_plan (2);
EXECUTE prep_select_plan (3);
DEALLOCATE prep_select_plan;
```

## 另请参阅
<a name="r_PREPARE-see-also"></a>

 [DEALLOCATE](r_DEALLOCATE.md), [EXECUTE](r_EXECUTE.md) 

# REFRESH MATERIALIZED VIEW
<a name="materialized-view-refresh-sql-command"></a>

刷新实体化视图。

创建实体化视图时，其内容将反映当时基础数据库表的状态。实体化视图中的数据将保持不变，即使应用程序更改基础表中的数据也是如此。

要更新实体化视图中的数据，您可以随时使用 `REFRESH MATERIALIZED VIEW` 语句。使用此语句时，Amazon Redshift 会标识已在一个或多个基表中进行的更改，然后将这些更改应用于实体化视图。

有关实体化视图的更多信息，请参阅[Amazon Redshift 中的实体化视图](materialized-view-overview.md)。

## 语法
<a name="mv_REFRESH_MATERIALIZED_VIEW-synopsis"></a>

```
REFRESH MATERIALIZED VIEW mv_name [ RESTRICT | CASCADE ]
```

## 参数
<a name="mv_REFRESH_MATERIALIZED_VIEW-parameters"></a>

*mv\$1name*  
要刷新的实体化视图的名称。

RESTRICT  
可选关键字。刷新指定的实体化视图，但不刷新其相关实体化视图。如果既未指定 RESTRICT，也未指定 CASCADE，则为默认值。

CASCADE  
可选关键字。刷新指定的实体化视图及其所有相关实体化视图。

## 使用说明
<a name="mv_REFRESH_MARTERIALIZED_VIEW_usage"></a>

只有实体化视图的拥有者才能对该实体化视图执行 `REFRESH MATERIALIZED VIEW` 操作。此外，所有者必须对基础基表具有 SELECT 权限才能成功运行 `REFRESH MATERIALIZED VIEW`。

`REFRESH MATERIALIZED VIEW` 命令作为其自己的事务运行。遵循 Amazon Redshift 事务语义来确定基表中的哪些数据对于 `REFRESH` 命令是可见的，或者何时使命令 `REFRESH` 所做的更改对 Amazon Redshift 中运行的其他事务可见。
+ 对于增量实体化视图，`REFRESH MATERIALIZED VIEW` 操作仅使用那些已提交的基表行。因此，如果刷新操作在同一事务中的数据操作语言 (DML) 语句之后运行，则对该 DML 语句的更改将对于刷新不可见。
+ 对于实体化视图的完全刷新，根据通常的 Amazon Redshift 事务语义，`REFRESH MATERIALIZED VIEW` 会看到对刷新事务可见的所有基表行。
+ 根据输入参数类型，Amazon Redshift 仍支持以下采用特定输入参数类型的函数所对应的实体化视图的增量刷新：DATE（时间戳）、DATE\$1PART（日期、时间、间隔、time-tz）、DATE\$1TRUNC（时间戳、间隔）。
+ 基表位于数据共享中的实例化视图支持增量刷新。
+ 对于包含对其它实体化视图、Spectrum 表、在不同 Redshift 集群中定义的表或 UDF 的引用的实体化视图，不支持从远程数据共享集群刷新共享的实体化视图。可以从本地（生产者）集群刷新此类实体化视图。

Amazon Redshift 中的一些操作会与实体化视图进行交互。这些操作中的某些操作可能会强制 `REFRESH MATERIALIZED VIEW` 完全重新计算实体化视图，即使定义该视图的查询仅使用可以用于增量刷新的 SQL 功能。例如：
+ 如果未刷新实体化视图，则可能会阻止后台 vacuum 操作。在内部定义的阈值期后，将允许运行 vacuum 操作。在发生此 vacuum 操作时，所有依赖的实体化视图都将标记为在下次刷新时重新计算（即使它们是增量的）。有关 VACUUM 的信息，请参阅 [VACUUM](r_VACUUM_command.md)。有关事件和状态更改的更多信息，请参阅 [STL\$1MV\$1STATE](r_STL_MV_STATE.md)。
+ 一些由用户对基表发起的操作会强制在下次运行 REFRESH 操作时完全重新计算实体化视图。此类操作的示例包括手动调用的 VACUUM、经典调整大小、ALTER DISTKEY 操作、ALTER SORTKEY 操作和截断操作。在某些情况下，自动操作还可能导致在下次运行 REFRESH 操作时完全重新计算实体化视图。例如，auto-vacuum 删除操作可能会导致完全重新计算。有关事件和状态更改的更多信息，请参阅 [STL\$1MV\$1STATE](r_STL_MV_STATE.md)。

## 级联刷新
<a name="mv_REFRESH_MATERIALIZED_VIEW_cascading"></a>

CASCADE 选项按相关性顺序来刷新指定的实体化视图及其所有相关实体化视图：先刷新基本 MV，然后再刷新顶部的 MV（拓扑排序）。这可让您在单个命令中更新一组嵌套的实体化视图。

RESTRICT 选项（如果既未指定 RESTRICT，也未指定 CASCADE，则该选项为默认值）仅刷新指定的实体化视图。

使用 CASCADE 选项时，以下规则适用：
+ 只有实体化视图的所有者或超级用户才可执行 `REFRESH MATERIALIZED VIEW ... CASCADE` 命令。
+ 如果无法刷新级联中的任何实体化视图，则整个级联操作将停止。

只有嵌套在本地和流式实体化视图之上的 MV 才支持级联刷新功能。在级联模式下不支持具有其它源类型（例如 Spectrum 或数据共享）的实体化视图。CASCADE 在单个事务中对所有嵌套 MV 执行刷新。

## 对数据共享中的实体化视图进行增量刷新
<a name="mv_REFRESH_MATERIALIZED_VIEW_datashare"></a>

 在共享基表时，Amazon Redshift 支持对消费者数据共享中的实体化视图进行自动和增量刷新。增量刷新是一项操作，其中 Amazon Redshift 可识别上次刷新后发生的一个或多个基表中的更改，并仅更新实体化视图中的相应记录。有关此行为的更多信息，请参阅 [CREATE MATERIALIZED VIEW](https://docs.aws.amazon.com/redshift/latest/dg/materialized-view-create-sql-command.html#mv_CREATE_MARTERIALIZED_VIEW_datashare)。

## 增量刷新限制
<a name="mv_REFRESH_MARTERIALIZED_VIEW_limitations"></a>

Amazon Redshift 目前不支持使用以下任意 SQL 元素通过查询定义的实体化视图的递增刷新：
+ OUTER JOIN（RIGHT、LEFT 或 FULL）。
+ 集操作：UNION、INTERSECT、EXCEPT、MINUS。
+ UNION ALL，当此参数出现在子查询中，并且查询中存在聚合函数或 GROUP BY 子句时，或者目标实体化视图包含排序键时。
+ 聚合函数：MEDIAN、PERCENTILE\$1CONT、LISTAGG、STDDEV\$1SAMP、STDDEV\$1POP、APPROXIMATE COUNT、APPROXIMATE PERCENTILE 以及按位聚合函数。
**注意**  
支持 COUNT、SUM、MIN、MAX 和 AVG 聚合函数。
+ DISTINCT 聚合函数，如 DISTINCT COUNT、DISTINCT SUM 等等。
+ 窗口函数。
+ 使用临时表进行查询优化的查询，例如优化常用的子表达式。
+ 子查询
+ 在定义实体化视图的查询中引用以下格式的外部表。
  +  Delta Lake 
  +  Hudi 

  对于使用上述格式以外的格式定义的实体化视图，支持增量刷新。有关更多信息，请参阅 [Amazon Redshift Spectrum 中外部数据湖表的实体化视图外部数据湖表的实体化视图](materialized-view-external-table.md)。
+ 可变函数，如日期-时间函数，RANDOM 和非 STABLE 用户定义函数。
+ 有关零 ETL 集成的增量刷新限制，请参阅[将零 ETL 集成与 Amazon Redshift 结合使用时的注意事项](https://docs.aws.amazon.com/redshift/latest/mgmt/zero-etl.reqs-lims.html)。
+ 从多个数据库访问表。

有关实体化视图限制的更多信息，包括 VACUUM 等后台操作对实体化视图刷新操作的影响，请参阅[使用说明](#mv_REFRESH_MARTERIALIZED_VIEW_usage)。

## 示例
<a name="mv_REFRESH_MARTERIALIZED_VIEW_examples"></a>

以下示例刷新 `tickets_mv` 实体化视图。

```
REFRESH MATERIALIZED VIEW tickets_mv;
```

以下示例刷新 `products_mv` 实体化视图及其所有相关实体化视图：

```
REFRESH MATERIALIZED VIEW products_mv CASCADE; 
```

# RESET
<a name="r_RESET"></a>

将配置参数的值还原为其默认值。

可以重置单个指定的参数或一次性重置所有参数。要将参数设置为特定的值，请使用 [SET](r_SET.md) 命令。要显示参数的当前值，请使用 [SHOW](r_SHOW.md) 命令。

## 语法
<a name="r_RESET-synopsis"></a>

```
RESET { parameter_name | ALL }
```

以下语句将会话上下文变量的值设置为 NULL。

```
RESET { variable_name | ALL }
```

## 参数
<a name="r_RESET-parameters"></a>

 *parameter\$1name*   
要重置的参数的名称。有关参数的更多文档，请参阅[修改服务器配置](cm_chap_ConfigurationRef.md#t_Modifying_the_default_settings)。

ALL   
重置所有运行时参数，包括所有会话上下文变量。

*variable*   
要重置的变量的名称。如果 RESET 的值是会话上下文变量，则 Amazon Redshift 会将它设置为 NULL。

## 示例
<a name="r_RESET-examples"></a>

以下示例将 `query_group` 参数重置为其默认值：

```
reset query_group;
```

以下示例将所有运行时参数重置为其默认值。

```
reset all;
```

以下示例重置上下文变量。

```
RESET app_context.user_id;
```

# REVOKE
<a name="r_REVOKE"></a>

从用户或角色删除访问权限，例如，用于创建、删除或更新表的权限。

您只能使用 ON SCHEMA 语法将针对外部架构的 GRANT 或 REVOKE USAGE 权限授予数据库用户和角色。将 ON EXTERNAL SCHEMA 与 AWS Lake Formation 搭配使用时，您只能向 AWS Identity and Access Management (IAM) 角色授予 GRANT 和 REVOKE 权限。有关权限的列表，请参阅“语法”。

对于存储过程，默认情况下，向 PUBLIC 授予 USAGE ON LANGUAGE `plpgsql` 权限。EXECUTE ON PROCEDURE 权限默认情况下只授予拥有者和超级用户。

在 REVOKE 命令中指定要删除的权限。要授予权限，请使用 [GRANT](r_GRANT.md) 命令。

## 语法
<a name="r_REVOKE-synopsis"></a>

```
REVOKE [ GRANT OPTION FOR ]
{ { SELECT | INSERT | UPDATE | DELETE | DROP | REFERENCES | ALTER | TRUNCATE } [,...] | ALL [ PRIVILEGES ] }
ON { [ TABLE ] table_name [, ...] | ALL TABLES IN SCHEMA schema_name [, ...] }
FROM { username | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
[ RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
{ { CREATE | TEMPORARY | TEMP | ALTER } [,...] | ALL [ PRIVILEGES ] }
ON DATABASE db_name [, ...]
FROM { username | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
[ RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
{ { CREATE | USAGE | ALTER | DROP } [,...] | ALL [ PRIVILEGES ] }
ON SCHEMA schema_name [, ...]
FROM { username | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
[ RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
EXECUTE
    ON FUNCTION function_name ( [ [ argname ] argtype [, ...] ] ) [, ...]
    FROM { username | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
[ RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
{ { EXECUTE } [,...] | ALL [ PRIVILEGES ] }
    ON PROCEDURE procedure_name ( [ [ argname ] argtype [, ...] ] ) [, ...]
    FROM { username | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
[ RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
USAGE
    ON LANGUAGE language_name [, ...]
    FROM { username | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
[ RESTRICT ]

REVOKE [GRANT OPTION FOR] 
{ { ALTER | DROP} [,...] | ALL [ PRIVILEGES ] }
    ON COPY JOB job_name [,...]
    FROM { username | ROLE role_name | GROUP group_name | PUBLIC } [, ...]    

REVOKE [GRANT OPTION FOR]
{ { ALTER | DROP | USAGE } [,...] | ALL [ PRIVILEGES ] }
    ON TEMPLATE template_name [,...]
    FROM { username | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
```

### 撤销表的列级别权限
<a name="revoke-column-level"></a>

以下是 Amazon Redshift 表和视图上的列级别权限的语法。

```
REVOKE { { SELECT | UPDATE } ( column_name [, ...] ) [, ...] | ALL [ PRIVILEGES ] ( column_name [,...] ) }
     ON { [ TABLE ] table_name [, ...] }
     FROM { username | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
     [ RESTRICT ]
```

### 撤销 ASSUMEROLE 权限
<a name="revoke-assumerole-permissions"></a>

以下是从具有指定角色的用户和组上撤销 ASSUMEROLE 权限的语法。

```
REVOKE ASSUMEROLE
    ON { 'iam_role' [, ...]  | default | ALL }
    FROM { user_name | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
    FOR { ALL | COPY | UNLOAD | EXTERNAL FUNCTION | CREATE MODEL }
```

### 撤销 Lake Formation 的 Redshift Spectrum 的权限
<a name="revoke-spectrum-integration-with-lf-permissions"></a>

以下是 Redshift Spectrum 与 Lake Formation 集成的语法。

```
REVOKE [ GRANT OPTION FOR ]
{ SELECT | ALL [ PRIVILEGES ] } ( column_list )
    ON EXTERNAL TABLE schema_name.table_name
    FROM { IAM_ROLE iam_role } [, ...]

REVOKE [ GRANT OPTION FOR ]
{ { SELECT | ALTER | DROP | DELETE | INSERT }  [, ...] | ALL [ PRIVILEGES ] }
    ON EXTERNAL TABLE schema_name.table_name [, ...]
    FROM { { IAM_ROLE iam_role } [, ...] | PUBLIC }

REVOKE [ GRANT OPTION FOR ]
{ { CREATE | ALTER | DROP }  [, ...] | ALL [ PRIVILEGES ] }
    ON EXTERNAL SCHEMA schema_name [, ...]
    FROM { IAM_ROLE iam_role } [, ...]
```

### 撤销数据共享权限
<a name="revoke-datashare-permissions"></a>

**生产者端数据共享权限**  
以下是使用 REVOKE 删除用户或角色的 ALTER 或 SHARE 权限的语法。权限已被撤销的用户无法再更改数据共享，也无法向使用者授予使用权限。

```
REVOKE { ALTER | SHARE } ON DATASHARE datashare_name
 FROM { username [ WITH GRANT OPTION ] | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
```

以下是使用 REVOKE 删除使用者对数据共享的访问权限的语法。

```
REVOKE USAGE
 ON DATASHARE datashare_name
 FROM NAMESPACE 'namespaceGUID' [, ...] | ACCOUNT 'accountnumber' [ VIA DATA CATALOG ] [, ...]
```

以下是从 Lake Formation 账户中撤销数据共享使用权限的示例。

```
REVOKE USAGE ON DATASHARE salesshare FROM ACCOUNT '123456789012' VIA DATA CATALOG;
```

**使用者端数据共享权限**  
以下是根据数据共享创建的特定数据库或 schema 的 REVOKE 数据共享使用权限的语法。撤销使用 WITH PERMISSIONS 子句创建的数据库的使用权限并不能撤销您授予用户或角色的任何其他权限，包括为基础对象授予的对象级权限。如果您向该用户或角色重新授予使用权限，他们将保留在您撤销使用权限之前拥有的所有其他权限。

```
REVOKE USAGE ON { DATABASE shared_database_name [, ...] | SCHEMA shared_schema}
 FROM { username | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
```

### 撤销限定范围权限
<a name="revoke-scoped-permissions"></a>

限定范围权限允许您向用户或角色授予对数据库或架构中某一类型的所有对象的访问权限。具有限定范围权限的用户和角色对数据库或架构中的所有当前和未来对象具有指定权限。

您可以在 [SVV\$1DATABASE\$1PRIVILEGES](r_SVV_DATABASE_PRIVILEGES.md) 中查看数据库级限定权限的范围。您可以在 [SVV\$1SCHEMA\$1PRIVILEGES](r_SVV_SCHEMA_PRIVILEGES.md) 中查看架构级限定权限的范围。

有关限定范围权限的更多信息，请参阅[限定范围权限](t_scoped-permissions.md)。

以下是撤销用户和角色的限定范围权限的语法。

```
REVOKE [ GRANT OPTION ] 
{ CREATE | USAGE | ALTER | DROP } [,...] | ALL [ PRIVILEGES ] }
FOR SCHEMAS IN
DATABASE db_name 
FROM { username | ROLE role_name } [, ...]

REVOKE [ GRANT OPTION ]
{ { SELECT | INSERT | UPDATE | DELETE | DROP | ALTER | TRUNCATE | REFERENCES } [, ...] } | ALL [PRIVILEGES] } }
FOR TABLES IN
{ SCHEMA schema_name [ DATABASE db_name ] | DATABASE db_name }
FROM { username | ROLE role_name } [, ...]

REVOKE [ GRANT OPTION ] { EXECUTE | ALL [ PRIVILEGES ] }
FOR FUNCTIONS IN 
{ SCHEMA schema_name [DATABASE db_name ] | DATABASE db_name }
FROM { username | ROLE role_name } [, ...]

REVOKE [ GRANT OPTION ] { EXECUTE | ALL [ PRIVILEGES ] }
FOR PROCEDURES IN
{ SCHEMA schema_name [DATABASE db_name ] | DATABASE db_name }
FROM { username | ROLE role_name } [, ...]

REVOKE [ GRANT OPTION ] USAGE
FOR LANGUAGES IN
DATABASE db_name
FROM { username | ROLE role_name } [, ...]  

REVOKE [GRANT_OPTION] 
{ { CREATE | ALTER | DROP} [,...] | ALL [ PRIVILEGES ] }
FOR COPY JOBS 
IN DATABASE db_name
FROM { username [ WITH GRANT OPTION ] | ROLE role_name } [, ...]      

REVOKE [ GRANT OPTION ]
{ {ALTER | DROP  | USAGE } [,...] | ALL [ PRIVILEGES ] }
FOR TEMPLATES IN
{ SCHEMA schema_name [DATABASE db_name ] | DATABASE db_name }
FROM { username | ROLE role_name } [, ...]
```

请注意，范围限定的权限不区分函数的权限和过程的权限。例如，以下语句撤销 `bob` 对架构 `Sales_schema` 中函数和过程的 `EXECUTE` 权限。

```
REVOKE EXECUTE FOR FUNCTIONS IN SCHEMA Sales_schema FROM bob;
```

### 撤销机器学习权限
<a name="revoke-model-permissions"></a>

以下是有关 Amazon Redshift 上机器学习模型权限的语法。

```
REVOKE [ GRANT OPTION FOR ]
    CREATE MODEL FROM { username | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
    [ RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
    { EXECUTE | ALL [ PRIVILEGES ] }
    ON MODEL model_name [, ...]

    FROM { username | ROLE role_name | GROUP group_name | PUBLIC } [, ...]
    [ RESTRICT ]
```

### 撤销角色权限
<a name="revoke-roles"></a>

以下是撤销在 Amazon Redshift 上的角色权限的语法。

```
REVOKE [ ADMIN OPTION FOR ] { ROLE role_name } [, ...] FROM { user_name } [, ...]
```

```
REVOKE { ROLE role_name } [, ...] FROM { ROLE role_name } [, ...]
```

以下是撤销角色在 Amazon Redshift 上的系统权限的语法。

```
REVOKE
  {
    { CREATE USER | DROP USER | ALTER USER |
    CREATE SCHEMA | DROP SCHEMA |
    ALTER DEFAULT PRIVILEGES |
    ACCESS CATALOG |
    CREATE TABLE | DROP TABLE | ALTER TABLE |
    CREATE OR REPLACE FUNCTION | CREATE OR REPLACE EXTERNAL FUNCTION |
    DROP FUNCTION |
    CREATE OR REPLACE PROCEDURE | DROP PROCEDURE |
    CREATE OR REPLACE VIEW | DROP VIEW |
    CREATE MODEL | DROP MODEL |
    CREATE DATASHARE | ALTER DATASHARE | DROP DATASHARE |
    CREATE LIBRARY | DROP LIBRARY |
    CREATE ROLE | DROP ROLE
    TRUNCATE TABLE
    VACUUM | ANALYZE | CANCEL }[, ...]
  }
  | { ALL [ PRIVILEGES ] }
FROM { ROLE role_name } [, ...]
```

### 撤销对安全性策略的权限
<a name="revoke-role-level"></a>

以下语法用于撤销解释 EXPLAIN 计划中查询的安全性策略筛选条件的权限。可能的安全性策略包括行级安全性策略和动态数据掩蔽策略。

```
REVOKE EXPLAIN { RLS | MASKING } FROM ROLE rolename 
```

以下语法用于撤销为查询绕开行级安全性策略的权限。

```
REVOKE IGNORE RLS FROM ROLE rolename 
```

以下语法用于从指定的安全性策略撤销 SELECT 权限。可能的安全性策略包括行级安全性策略和动态数据掩蔽策略。

```
REVOKE SELECT ON [ TABLE ] table_name [, ...]
            FROM { RLS | MASKING } POLICY policy_name [, ...]
```

## 参数
<a name="r_REVOKE-parameters"></a>

GRANT OPTION FOR   
仅撤消将指定权限授予其他用户的选项，而不撤消权限本身。您无法从组或 PUBLIC 撤消 GRANT OPTION。

SELECT   
撤消用于通过 SELECT 语句从表或视图中选择数据的权限。

INSERT   
撤消用于通过 INSERT 语句或 COPY 语句将数据加载到表中的权限。

UPDATE   
撤消用于通过 UPDATE 语句更新表列的权限。

DELETE   
撤消用于从表中删除数据行的权限。

REFERENCES   
撤消用于创建外键约束的权限。您应该在被引用表和引用表上撤消此权限。

TRUNCATE  
撤销截断表的权限。如果没有此权限，则只有表的拥有者或超级用户才可以截断表。有关 TRUNCATE 命令的更多信息，请参阅 [TRUNCATE](r_TRUNCATE.md)。

ALL [ PRIVILEGES ]   
一次性从指定的用户或组撤消所有可用权限。PRIVILEGES 关键字是可选的。  
 Amazon Redshift 不支持 RULE 和 TRIGGER 权限。有关更多信息，请转至 [不支持的 PostgreSQL 功能](c_unsupported-postgresql-features.md)。

ALTER  
根据数据库对象，从用户或用户组撤销以下权限：  
+ 对于表，ALTER 撤销更改表或视图的权限。有关更多信息，请参阅 [ALTER TABLE](r_ALTER_TABLE.md)。
+ 对于数据库，ALTER 撤销更改更数据库的权限。有关更多信息，请参阅 [ALTER DATABASE](r_ALTER_DATABASE.md)。
+ 对于架构，ALTER 撤销更改模式的权限。有关更多信息，请参阅 [ALTER SCHEMA](r_ALTER_SCHEMA.md)。
+ 对于外部表，ALTER 撤销对为 Lake Formation 启用的 AWS Glue Data Catalog 中的表进行更改的权限。此权限仅在使用 Lake Formation 时适用。

DROP  
根据数据库对象，从用户或角色撤销以下权限：  
+  对于表，DROP 撤销删除表或视图的权限。有关更多信息，请参阅 [DROP TABLE](r_DROP_TABLE.md)。
+  对于数据库，DROP 撤销删除数据库的权限。有关更多信息，请参阅 [DROP DATABASE](r_DROP_DATABASE.md)。
+  对于架构，DROP 撤销删除架构的权限。有关更多信息，请参阅 [DROP SCHEMA](r_DROP_SCHEMA.md)。

ASSUMEROLE  <a name="assumerole"></a>
从具有指定角色的用户、角色或组撤消运行 COPY、UNLOAD、EXTERNAL FUNCTION 或 CREATE MODEL 命令的权限。

ON [ TABLE ] *table\$1name*   
撤消对表或视图的指定权限。TABLE 关键字是可选的。

ON ALL TABLES IN SCHEMA *schema\$1name*   
撤消对引用的 Schema 中的所有表的指定权限。

( *column\$1name* [,...] ) ON TABLE *table\$1name*   <a name="revoke-column-level-privileges"></a>
撤消用户、组或 PUBLIC 对 Amazon Redshift 表或视图的指定列的指定权限。

( *column\$1list* ) ON EXTERNAL TABLE *schema\$1name.table\$1name*   <a name="revoke-external-table-column"></a>
从 IAM 角色撤消对于引用的 Schema 中 Lake Formation 表的指定列的指定权限。

ON EXTERNAL TABLE *schema\$1name.table\$1name*   <a name="revoke-external-table"></a>
从 IAM 角色撤消对于引用的 Schema 中的指定 Lake Formation 表的指定权限。

ON EXTERNAL SCHEMA *schema\$1name*   <a name="revoke-external-schema"></a>
从 IAM 角色撤消对于引用的 Schema 的指定权限。

FROM IAM\$1ROLE *iam\$1role*   <a name="revoke-from-iam-role"></a>
表示丢失权限的 IAM 角色。

ROLE *role\$1name*   
从指定的角色撤销权限。

GROUP *group\$1name*   
从指定的用户组撤消权限。

PUBLIC   
从所有用户撤消指定权限。PUBLIC 表示一个始终包含所有用户的组。单个用户的权限包含向 PUBLIC 授予的权限、向用户所属的所有组授予的权限以及向用户单独授予的任何权限。  
从 Lake Formation 外部表中撤销 PUBLIC 会将该权限从 Lake Formation *所有人*组撤销。

CREATE   
根据数据库对象，从用户或组撤销以下权限：  
+ 对于数据库，对 REVOKE 使用 CREATE 子句将阻止用户在数据库中创建 schema。
+ 对于 schemas，对 REVOKE 使用 CREATE 子句将阻止用户在 schema 中创建对象。要重命名对象，用户必须具有 CREATE 权限并拥有要重命名的对象。
默认情况下，所有用户都对 PUBLIC Schema 具有 CREATE 和 USAGE 权限。

TEMPORARY \$1 TEMP   
撤销在指定的数据库中创建临时表的权限。  
默认情况下，向用户授予权限以通过其在 PUBLIC 组中自动获得的成员资格来创建临时表。要删除任意用户创建临时表的权限，请撤销 PUBLIC 组的 TEMP 权限，然后明确向特定用户或用户组授予用于创建临时表的权限。

ON DATABASE *db\$1name*   
撤销对指定数据库的权限。

USAGE   
撤销对特定架构中的对象的 USAGE 权限，这将使用户无法访问这些对象。必须单独撤销这些对象的特定操作权限（例如，对函数的 EXECUTE 权限）。  
默认情况下，所有用户都对 PUBLIC Schema 具有 CREATE 和 USAGE 权限。

ON SCHEMA *schema\$1name*   
撤销对指定架构的权限。您可以使用架构权限来控制表的创建；数据库的 CREATE 权限仅控制架构的创建。

RESTRICT   
仅撤销用户直接授予的那些权限。此行为是默认行为。

EXECUTE ON PROCEDURE *procedure\$1name*   
撤销对特定存储过程的 EXECUTE 权限。由于存储过程名称可重载，因此您必须包含过程的参数列表。有关更多信息，请参阅 [命名存储过程](stored-procedure-naming.md)。

EXECUTE ON ALL PROCEDURES IN SCHEMA *procedure\$1name*   
撤销对引用的架构中的所有过程的指定权限。

USAGE ON LANGUAGE *language\$1name*   
撤销对某种语言的 USAGE 权限。对于 Python 用户定义的函数 (UDF)，请使用 `plpythonu`。对于 SQL UDF，使用 `sql`。对于存储过程，请使用 `plpgsql`。  
要创建 UDF，您必须具有使用 SQL 或 `plpythonu` (Python) 语言的权限。默认情况下，向 PUBLIC 授予 USAGE ON LANGUAGE SQL。但是，您必须明确授予 USAGE ON LANGUAGE PLPYTHONU 权限才能指定用户或组。  
要撤销 SQL 的使用权限，请先从 PUBLIC 撤销使用权限。然后，仅向允许创建 SQL UDF 的特定用户或组授予 SQL 使用权限。以下示例将从 PUBLIC 撤销对 SQL 的使用权限，然后向用户组 `udf_devs` 授予使用权限。  

```
revoke usage on language sql from PUBLIC;
grant usage on language sql to group udf_devs;
```
有关更多信息，请参阅 [UDF 安全性和权限](udf-security-and-privileges.md)。  
要撤销存储过程的使用权限，请先从 PUBLIC 撤销使用权限。然后，仅向允许创建存储过程的特定用户或组授予 `plpgsql` 使用权限。有关更多信息，请参阅 [存储过程的安全性和权限](stored-procedure-security-and-privileges.md)。

ON COPY JOB *job\$1name*  <a name="on-copy-job-revoke"></a>
撤销对复制作业的指定权限。

FOR \$1 ALL \$1 COPY \$1 UNLOAD \$1 EXTERNAL FUNCTION \$1 CREATE MODEL \$1 [, ...]  <a name="revoke-for"></a>
指定撤销其权限的 SQL 命令。您可以指定 ALL 以撤销对 COPY、UNLOAD、EXTERNAL FUNCTION 和 CREATE MODEL 语句的权限。此子句仅适用于撤销 ASSUMEROLE 权限。

ALTER  
撤销用户或用户组的 ALTER 权限，允许那些不拥有数据共享的用户或用户组更改数据共享。将对象添加到数据共享中或从中删除，或设置属性 PUBLICACCESSIBLE 时需要此权限。有关更多信息，请参阅 [ALTER DATASHARE](r_ALTER_DATASHARE.md)。

SHARE  
撤销用户和用户组将使用者添加到数据共享的权限。需要撤销此权限才能阻止特定使用者从其集群访问数据共享。

ON DATASHARE *datashare\$1name *  
授予对被引用数据共享的指定权限。

FROM 用户名  
指示失去权限的用户。

FROM GROUP *group\$1name*  
指示失去权限的用户组。

WITH GRANT OPTION  
指示失去权限的用户随之可以对其他用户撤销相同的权限。您无法为组或 PUBLIC 撤消 WITH GRANT OPTION。

USAGE  
撤销同一账户中的使用者账户或命名空间的 USAGE 时，该账户中的特定使用者账户或命名空间不能以只读方式访问数据共享和数据共享的对象。  
撤销 USAGE 权限将撤销使用者对数据共享的访问权限。

FROM NAMESPACE 'clusternamespace GUID'  
指示同一账户中使用者失去对数据共享的权限的命名空间。命名空间使用 128 位字母数字全局唯一标识符 (GUID)。

FROM ACCOUNT 'accountnumber' [ VIA DATA CATALOG ]  
指示另一个账户中使用者失去对数据共享的权限的账号。指定‘VIA DATA CATALOG’表示您要从 Lake Formation 账户撤销使用数据共享的权限。省略账号意味着您要撤销拥有集群的账户的权限。

ON DATABASE *shared\$1database\$1name> [, ...]*   <a name="revoke-datashare"></a>
撤销对在指定数据共享中创建的指定数据库的指定使用权限。

ON SCHEMA* shared\$1schema*   <a name="revoke-datashare"></a>
撤销对在指定数据共享中创建的指定架构的指定权限。

FOR \$1 SCHEMAS \$1 TABLES \$1 FUNCTIONS \$1 PROCEDURES \$1 LANGUAGES \$1 COPY JOBS\$1 IN   
指定要撤销权限的数据库对象。IN 后面的参数定义了所撤销权限的范围。

CREATE MODEL  
撤销 CREATE MODEL 在指定数据库中创建机器学习模型的权限。

ON MODEL *model\$1name*  
撤销特定模型的 EXECUTE 权限。

ACCESS CATALOG  
撤销查看该角色可访问对象的相关元数据的权限。

[ ADMIN OPTION FOR ] \$1 role \$1 [, ...]  
您从具有 WITH ADMIN OPTION 的指定用户撤销的角色。

FROM \$1 role \$1 [, ...]  
从其撤消了指定角色的角色。

EXPLAIN \$1 RLS \$1 MASKING \$1 FROM ROLE *rolename*  
从角色撤销用于解释 EXPLAIN 计划中查询的安全性策略筛选条件的权限。RLS 撤销解释行级安全性策略筛选条件的权限。MASKING 撤销解释动态数据掩蔽策略筛选条件的权限。

IGNORE RLS FROM ROLE *rolename*   
从角色撤销绕开查询的行级安全性策略的权限。

FROM \$1 RLS \$1 MASKING \$1 POLICY *policy\$1name*  
指示失去权限的安全性策略。TO RLS POLICY 表示行级安全性策略。TO MASKING POLICY 表示动态数据掩蔽策略。

## 使用说明
<a name="r_REVOKE-usage-notes-link"></a>

要了解有关 REVOKE 使用说明的更多信息，请参阅[使用说明](r_REVOKE-usage-notes.md)。

## 示例
<a name="r_REVOKE-examples-link"></a>

有关如何使用 REVOKE 的示例，请参阅[示例](r_REVOKE-examples.md)。

# 使用说明
<a name="r_REVOKE-usage-notes"></a>

要撤消对象的权限，您必须满足下列条件之一：
+ 是对象所有者。
+ 是超级用户。
+ 拥有该对象和权限的授予权限。

  例如，以下命令使用户 HR 能够对 employees 表执行 SELECT 命令并对其他用户授予和撤销相同的权限。

  ```
  grant select on table employees to HR with grant option;
  ```

  HR 无法撤销 SELECT 之外的任何操作的权限或 employees 表之外的任何其他表的权限。

超级用户可以访问所有对象，不管设置对象权限的 GRANT 和 REVOKE 命令如何。

PUBLIC 表示一个始终包含所有用户的组。默认情况下，PUBLIC 的所有成员都对 PUBLIC schema 具有 CREATE 和 USAGE 权限。要限制任何用户对 PUBLIC schema 的权限，您必须首先从 PUBLIC 撤销对 PUBLIC schema 的所有权限，然后向特定用户或组授予权限。以下示例控制 PUBLIC schema 中的表创建权限。

```
revoke create on schema public from public;
```

要从 Lake Formation 表撤销权限，与表的外部架构关联的 IAM 角色必须有权撤销对外部表的权限。以下示例创建具有关联 IAM 角色 `myGrantor` 的外部架构。IAM 角色 `myGrantor` 有权撤销其他角色的权限。REVOKE 命令使用与外部架构关联的 IAM 角色 `myGrantor` 的权限来撤销对 IAM 角色 `myGrantee` 的权限。

```
create external schema mySchema
from data catalog
database 'spectrum_db'
iam_role 'arn:aws:iam::123456789012:role/myGrantor'
create external database if not exists;
```

```
revoke select
on external table mySchema.mytable
from iam_role 'arn:aws:iam::123456789012:role/myGrantee';
```

**注意**  
如果 IAM 角色在为 Lake Formation 启用的 AWS Glue Data Catalog 中也有 `ALL` 权限，则不会撤销 `ALL` 权限。只撤销 `SELECT` 权限。您可以在 Lake Formation 控制台中查看 Lake Formation 权限。

## 有关撤销 ASSUMEROLE 权限的使用说明
<a name="r_REVOKE-usage-notes-assumerole"></a>

以下使用说明适用于在 Amazon Redshift 中撤销 ASSUMEROLE 权限。

只有数据库超级用户才可以撤消用户和组的 ASSUMEROLE 权限。超级用户始终会保留 ASSUMEROLE 权限。

要为用户和组启用 ASSUMEROLE 的使用权限，超级用户要在集群上运行一次以下语句。要为用户和组启用 ASSUMEROLE 的使用权限，超级用户要在集群上将以下语句运行一次。

```
revoke assumerole on all from public for all;
```

## 有关撤销机器学习权限的使用说明
<a name="r_REVOKE-usage-notes-create-model"></a>

您不能直接授予或撤销与机器学习函数相关的权限。机器学习函数属于机器学习模型，其权限通过模型来控制。相反，您可以撤销与机器学习模型相关的权限。以下示例演示如何从与模型 `customer_churn` 关联的所有用户撤销运行权限。

```
REVOKE EXECUTE ON MODEL customer_churn FROM PUBLIC;
```

您还可以撤销某个用户对机器学习模型 `customer_churn` 的所有权限。

```
REVOKE ALL on MODEL customer_churn FROM ml_user;
```

如果架构中有机器学习函数，则授予或撤销与机器学习函数相关的 `EXECUTE` 权限将失败，即使该机器学习函数已通过 `GRANT EXECUTE ON MODEL` 获得 `EXECUTE` 权限。我们建议在使用 `CREATE MODEL` 命令时，通过单独的架构将机器学习函数单独保存在单独架构本身中。以下示例演示了如何执行此操作。

```
CREATE MODEL ml_schema.customer_churn
FROM customer_data
TARGET churn
FUNCTION ml_schema.customer_churn_prediction
IAM_ROLE default
SETTINGS (
 S3_BUCKET 'amzn-s3-demo-bucket'
);
```

# 示例
<a name="r_REVOKE-examples"></a>

以下示例从 GUESTS 用户组撤消对 SALES 表的 INSERT 权限。此命令使 GUESTS 的成员无法通过使用 INSERT 命令将数据加载到 SALES 表中。

```
revoke insert on table sales from group guests;
```

以下示例从用户 `fred` 撤消对 QA\$1TICKIT 架构中所有表的 SELECT 权限。

```
revoke select on all tables in schema qa_tickit from fred;
```

以下示例撤消用户 `bobr` 从视图中选择的权限。

```
revoke select on table eventview from bobr;
```

以下示例从所有用户撤消在 TICKIT 数据库中创建临时表的权限。

```
revoke temporary on database tickit from public;
```

以下示例从用户 `cust_name` 撤消对 `cust_phone` 表的 `cust_profile` 和 `user1` 列的 SELECT 权限。

```
revoke select(cust_name, cust_phone) on cust_profile from user1;
```

以下示例从 `cust_name` 组中撤消对 `cust_phone` 和 `cust_contact_preference` 列的 SELECT 权限，并撤消对 `cust_profile` 表的 `sales_group` 列的 UPDATE 权限。

```
revoke select(cust_name, cust_phone), update(cust_contact_preference) on cust_profile from group sales_group;
```

下面的示例演示如何使用 ALL 关键字从 `cust_profile` 组撤消对 `sales_admin` 表的三列的 SELECT 和 UPDATE 权限。

```
revoke ALL(cust_name, cust_phone,cust_contact_preference) on cust_profile from group sales_admin;
```

以下示例从 `cust_name` 用户撤消对 `cust_profile_vw` 视图的 `user2` 列的 SELECT 权限。

```
revoke select(cust_name) on cust_profile_vw from user2;
```

## 撤销通过数据共享创建的数据库的 USAGE 权限的示例
<a name="r_REVOKE-examples-datashare"></a>

以下示例从 `13b8833d-17c6-4f16-8fe4-1a018f5ed00d` 命名空间撤销对 `salesshare` 数据共享的访问权限。

```
REVOKE USAGE ON DATASHARE salesshare FROM NAMESPACE '13b8833d-17c6-4f16-8fe4-1a018f5ed00d';
```

以下示例从 `Bob` 撤销对 `sales_db` 的 USAGE 权限。

```
REVOKE USAGE ON DATABASE sales_db FROM Bob;
```

以下示例从 `Analyst_role` 撤销对 `sales_schema` 的 USAGE 权限。

```
REVOKE USAGE ON SCHEMA sales_schema FROM ROLE Analyst_role;
```

## 撤销限定范围权限的示例
<a name="r_REVOKE-examples-scoped"></a>

以下示例从 `Sales` 角色撤销 `Sales_db` 数据库中所有当前和将来架构的使用权限。

```
REVOKE USAGE FOR SCHEMAS IN DATABASE Sales_db FROM ROLE Sales;
```

以下示例从用户 `alice` 撤销授予对 `Sales_db` 数据库中所有当前和将来表的 SELECT 权限的能力。`alice` 保留对 `Sales_db` 中所有表的访问权限。

```
REVOKE GRANT OPTION SELECT FOR TABLES IN DATABASE Sales_db FROM alice;
```

以下示例从用户 `bob` 撤销对 `Sales_schema` 架构中函数的 EXECUTE 权限。

```
REVOKE EXECUTE FOR FUNCTIONS IN SCHEMA Sales_schema FROM bob;
```

以下示例从 `Sales` 角色撤销对 `ShareDb` 数据库 `ShareSchema` 架构中所有表的所有权限。指定架构时，您还可以使用由两部分组成的格式 `database.schema` 指定架构的数据库。

```
REVOKE ALL FOR TABLES IN SCHEMA ShareDb.ShareSchema FROM ROLE Sales;
```

下面的示例与前一个示例相同。您可以使用 `DATABASE` 关键字而不是使用由两部分组成的格式来指定架构的数据库。

```
REVOKE ALL FOR TABLES IN SCHEMA ShareSchema DATABASE ShareDb FROM ROLE Sales;
```

## 撤销 ASSUMEROLE 权限的示例
<a name="r_REVOKE-examples-assumerole"></a>

以下是撤销 ASSUMEROLE 权限的示例。

超级用户必须通过在集群上运行一次以下语句来为用户和组启用 ASSUMEROLE 的使用权限。

```
revoke assumerole on all from public for all;
```

以下语句撤消用户 reg\$1user1 在所有角色中对所有操作的 ASSUMEROLE 权限。

```
revoke assumerole on all from reg_user1 for all;
```

## 撤销 ROLE 权限的示例
<a name="r_REVOKE-examples-role"></a>

下面的示例将从 sample\$1role2 撤销 sample\$1role1。

```
CREATE ROLE sample_role2;
GRANT ROLE sample_role1 TO ROLE sample_role2;
REVOKE ROLE sample_role1 FROM ROLE sample_role2;
```

下面的示例将撤销 user1 的系统权限。

```
GRANT ROLE sys:DBA TO user1;
REVOKE ROLE sys:DBA FROM user1;
```

下面的示例将从 user1 撤销 sample\$1role1 和 sample\$1role2。

```
CREATE ROLE sample_role1;
CREATE ROLE sample_role2;
GRANT ROLE sample_role1, ROLE sample_role2 TO user1;
REVOKE ROLE sample_role1, ROLE sample_role2 FROM user1;
```

下面的示例将从 user1 撤销具有 ADMIN OPTION 的 sample\$1role2。

```
GRANT ROLE sample_role2 TO user1 WITH ADMIN OPTION;
REVOKE ADMIN OPTION FOR ROLE sample_role2 FROM user1;
REVOKE ROLE sample_role2 FROM user1;
```

下面的示例将从 sample\$1role5 撤销 sample\$1role1 和 sample\$1role2。

```
CREATE ROLE sample_role5;
GRANT ROLE sample_role1, ROLE sample_role2 TO ROLE sample_role5;
REVOKE ROLE sample_role1, ROLE sample_role2 FROM ROLE sample_role5;
```

下面的示例将撤销 sample\$1role1 的 CREATE SCHEMA 和 DROP SCHEMA 系统权限。

```
GRANT CREATE SCHEMA, DROP SCHEMA TO ROLE sample_role1;
REVOKE CREATE SCHEMA, DROP SCHEMA FROM ROLE sample_role1;
```

# ROLLBACK
<a name="r_ROLLBACK"></a>

停止当前事务，并放弃该事务执行的所有更新。

此命令执行与 [ABORT](r_ABORT.md) 命令相同的功能。

## 语法
<a name="r_ROLLBACK-synopsis"></a>

```
ROLLBACK [ WORK | TRANSACTION ]
```

## 参数
<a name="r_ROLLBACK-parameters"></a>

WORK  
可选关键字。存储过程中不支持此关键字。

TRANSACTION  
可选关键字。WORK 和 TRANSACTION 是同义词。两者在存储过程中均不受支持。

有关在存储过程中使用 ROLLBACK 的信息，请参阅[管理事务](stored-procedure-transaction-management.md)。

## 示例
<a name="r_ROLLBACK-example"></a>

以下示例创建一个表，然后启动将数据插入到表的事务。然后，ROLLBACK 命令将回滚数据插入操作，以便将表保持为空表。

以下命令创建一个名为 MOVIE\$1GROSS 的示例表：

```
create table movie_gross( name varchar(30), gross bigint );
```

下一组命令启动将两个数据行插入到表中的事务：

```
begin;

insert into movie_gross values ( 'Raiders of the Lost Ark', 23400000);

insert into movie_gross values ( 'Star Wars', 10000000 );
```

接下来，以下命令从表中选择数据，表明已插入成功：

```
select * from movie_gross;
```

命令输出表明已成功插入两行：

```
name           |  gross
-------------------------+----------
Raiders of the Lost Ark | 23400000
Star Wars               | 10000000
(2 rows)
```

现在，此命令将数据更改回滚到事务开始的位置：

```
rollback;
```

现在，从表中选择数据时，显示这是一个空表：

```
select * from movie_gross;

name | gross
------+-------
(0 rows)
```

# SELECT
<a name="r_SELECT_synopsis"></a>

返回表、视图和用户定义的函数中的行。

**注意**  
单个 SQL 语句的最大大小为 16MB。

## 语法
<a name="r_SELECT_synopsis-synopsis"></a>

```
[ WITH with_subquery [, ...] ]
SELECT
[ TOP number | [ ALL | DISTINCT ]
* | expression [ AS output_name ] [, ...] ]
[ EXCLUDE column_list ]
[ FROM table_reference [, ...] ]
[ WHERE condition ]
[ [ START WITH expression ] CONNECT BY expression ]
[ GROUP BY ALL | expression [, ...] ]
[ HAVING condition ]
[ QUALIFY condition ]
[ { UNION | ALL | INTERSECT | EXCEPT | MINUS } query ]
[ ORDER BY expression [ ASC | DESC ] ]
[ LIMIT { number | ALL } ]
[ OFFSET start ]
```

**Topics**
+ [语法](#r_SELECT_synopsis-synopsis)
+ [WITH 子句](r_WITH_clause.md)
+ [SELECT 列表](r_SELECT_list.md)
+ [EXCLUDE column\$1list](r_EXCLUDE_list.md)
+ [FROM 子句](r_FROM_clause30.md)
+ [WHERE 子句](r_WHERE_clause.md)
+ [GROUP BY 子句](r_GROUP_BY_clause.md)
+ [HAVING 子句](r_HAVING_clause.md)
+ [QUALIFY 子句](r_QUALIFY_clause.md)
+ [UNION、INTERSECT 和 EXCEPT](r_UNION.md)
+ [ORDER BY 子句](r_ORDER_BY_clause.md)
+ [CONNECT BY 子句](r_CONNECT_BY_clause.md)
+ [子查询示例](r_Subquery_examples.md)
+ [关联的子查询](r_correlated_subqueries.md)

# WITH 子句
<a name="r_WITH_clause"></a>

WITH 子句是一个可选子句，该子句在查询中位于 SELECT 列表之前。WITH 子句定义一个或多个 *common\$1table\$1expressions*。每个通用表表达式 (CTE) 均定义一个临时表，它与视图定义类似。您可以在 FROM 子句中引用这些临时表。它们仅在它们所属的查询运行时使用。WITH 子句中的每个子 CTE 均指定一个表名、一个可选的列名称列表以及一个计算结果为表的查询表达式（SELECT 语句）。当您在定义临时表的同一查询表达式的 FROM 子句中引用临时表名时，CTE 是递归的。

WITH 子句子查询是定义可在单个查询的执行过程中使用的表的有效方式。在所有情况下，在 SELECT 语句的主体中使用子查询可获得相同的结果，不过 WITH 子句子查询可能在编写和阅读方面更加简单。如果可能，会将已引用多次的 WITH 子句子查询优化为常用子表达式；即，可以计算 WITH 子查询一次并重用其结果。（请注意，常用子表达式不只是限于 WITH 子句中定义的子表达式。）

## 语法
<a name="r_WITH_clause-synopsis"></a>

```
[ WITH [RECURSIVE] common_table_expression [, common_table_expression , ...] ]
```

其中 *common\$1table\$1expression* 可以是非递归的，也可以是递归的。以下是非递归形式：

```
CTE_table_name [ ( column_name [, ...] ) ] AS ( query )
```

以下是 *common\$1table\$1expression* 的递归形式：

```
CTE_table_name (column_name [, ...] ) AS ( recursive_query )
```

## 参数
<a name="r_WITH_clause-parameters"></a>

 RECURSIVE   
将查询标识为递归 CTE 的关键词。如果 WITH 子句中定义的任何 *common\$1table\$1expression* 是递归的，则需要此关键词。即使 WITH 子句包含多个递归 CTE，您也只能紧跟 WITH 关键词之后指定一次 RECURSIVE 关键词。通常，递归 CTE 是一个包含两个部分的 UNION ALL 子查询。

 *common\$1table\$1expression*   
定义一个您可以在 [FROM 子句](r_FROM_clause30.md) 中引用并且仅在执行其所属的查询期间使用的临时表。

 *CTE\$1table\$1name*   
临时表的唯一名称，该临时表用于定义 WITH 子句子查询的结果。不能在单个 WITH 子句中使用重复名称。必须为每个子查询提供一个可在 [FROM 子句](r_FROM_clause30.md)中引用的表名。

 *column\$1name*   
 WITH 子句子查询的输出列名称的列表（用逗号分隔）。指定的列名数目必须等于或小于子查询定义的列数。对于非递归的 CTE，*column\$1name* 子句是可选的。对于递归的 CTE，*column\$1name* 列表是必需的。

 *query*   
 Amazon Redshift 支持的任何 SELECT 查询。请参阅 [SELECT](r_SELECT_synopsis.md)。

 *recursive\$1query*   
由两个 SELECT 子查询组成的 UNION ALL 查询：  
+ 第一个 SELECT 子查询没有对同一个 *CTE\$1table\$1name* 进行递归引用。它返回一个结果集，该结果集是递归的初始种子。此部分称为初始成员或种子成员。
+ 第二个 SELECT 子查询在其 FROM 子句中引用同一个 *CTE\$1table\$1name*。它被称为递归成员。*recursive\$1query* 包含一个 WHERE 条件来结束 *recursive\$1query*。

## 使用说明
<a name="r_WITH_clause-usage-notes"></a>

可在以下 SQL 语句中使用 WITH 子句：
+ SELECT 
+ SELECT INTO
+ CREATE TABLE AS
+ CREATE VIEW
+ DECLARE
+ EXPLAIN
+ INSERT INTO...SELECT 
+ PREPARE
+ UPDATE（在 WHERE 子句子查询中。您无法在子查询中定义递归 CTE。递归 CTE 必须位于 UPDATE 子句之前。）
+ DELETE

如果包含 WITH 子句的查询的 FROM 子句未引用 WITH 子句所定义的任何表，则将忽略 WITH 子句，并且查询将正常执行。

WITH 子句子查询所定义的表只能在 WITH 子句开始的 SELECT 查询范围内引用。例如，可以在 SELECT 列表的子查询的 FROM 子句、WHERE 子句或 HAVING 子句中引用这样的表。不能在子查询中使用 WITH 子句，也不能在主查询或其他子查询的 FROM 子句中引用其表。此查询模式会为 WITH 子句表生成 `relation table_name doesn't exist` 形式的错误消息。

不能在 WITH 子句子查询中指定另一个 WITH 子句。

不能对 WITH 子句子查询定义的表进行前向引用。例如，以下查询返回一个错误，因为在表 W1 的定义中对表 W2 进行了前向引用：

```
with w1 as (select * from w2), w2 as (select * from w1)
select * from sales;
ERROR:  relation "w2" does not exist
```

WITH 子句子查询不能包含 SELECT INTO 语句；不过，您可以在 SELECT INTO 语句中使用 WITH 子句。

## 递归公用表表达式
<a name="r_WITH_clause-recursive-cte"></a>

递归*公用表表达式 (CTE)* 是一个引用自身的 CTE。递归 CTE 在查询分层数据（如显示员工和经理之间的报告关系的组织结构图）时非常有用。请参阅 [示例：递归 CTE](#r_WITH_clause-recursive-cte-example)。

另一个常见用途是多级物料清单，当产品由多个组件组成并且每个组件本身也包含其它组件或子装配件时。

通过在递归查询的第二个 SELECT 子查询中包含 WHERE 子句来确保限制递归的深度。有关示例，请参阅 [示例：递归 CTE](#r_WITH_clause-recursive-cte-example)。否则，可能会出现类似于以下内容的错误：
+ `Recursive CTE out of working buffers.`
+ `Exceeded recursive CTE max rows limit, please add correct CTE termination predicates or change the max_recursion_rows parameter.`

**注意**  
`max_recursion_rows` 参数用于设置递归 CTE 可以返回的最大行数，以防止无限递归循环。我们建议更改该值时不要超过默认值。这样可以防止查询中的无限递归问题占用集群的过多空间。

 您可以指定递归 CTE 结果的排序顺序和限制。您可以在递归 CTE 的最终结果中包含分组依据和不同选项。

不能在子查询中指定 WITH RECURSIVE 子句。*recursive\$1query* 成员不能包含排序依据或限制子句。

## 示例
<a name="r_WITH_clause-examples"></a>

以下示例说明了包含 WITH 语句的查询的最简单示例。在名为 VENUECOPY 的 WITH 查询中，选择 VENUE 表中的所有行。主查询又选择 VENUECOPY 中的所有行。VENUECOPY 表仅在此查询的持续时间内存在。

```
with venuecopy as (select * from venue)
select * from venuecopy order by 1 limit 10;
```

```
 venueid |         venuename          |    venuecity    | venuestate | venueseats
---------+----------------------------+-----------------+------------+------------
1 | Toyota Park                | Bridgeview      | IL         |          0
2 | Columbus Crew Stadium      | Columbus        | OH         |          0
3 | RFK Stadium                | Washington      | DC         |          0
4 | CommunityAmerica Ballpark  | Kansas City     | KS         |          0
5 | Gillette Stadium           | Foxborough      | MA         |      68756
6 | New York Giants Stadium    | East Rutherford | NJ         |      80242
7 | BMO Field                  | Toronto         | ON         |          0
8 | The Home Depot Center      | Carson          | CA         |          0
9 | Dick's Sporting Goods Park | Commerce City   | CO         |          0
v     10 | Pizza Hut Park             | Frisco          | TX         |          0
(10 rows)
```

以下示例显示一个 WITH 子句，该子句生成两个分别名为 VENUE\$1SALES 和 TOP\$1VENUES 的表。第二个 WITH 查询表从第一个表中进行选择。而主查询块的 WHERE 子句又包含一个约束 TOP\$1VENUES 表的子查询。

```
with venue_sales as
(select venuename, venuecity, sum(pricepaid) as venuename_sales
from sales, venue, event
where venue.venueid=event.venueid and event.eventid=sales.eventid
group by venuename, venuecity),

top_venues as
(select venuename
from venue_sales
where venuename_sales > 800000)

select venuename, venuecity, venuestate,
sum(qtysold) as venue_qty,
sum(pricepaid) as venue_sales
from sales, venue, event
where venue.venueid=event.venueid and event.eventid=sales.eventid
and venuename in(select venuename from top_venues)
group by venuename, venuecity, venuestate
order by venuename;
```

```
        venuename       |   venuecity   | venuestate | venue_qty | venue_sales
------------------------+---------------+------------+-----------+-------------
August Wilson Theatre   | New York City | NY         |      3187 |  1032156.00
Biltmore Theatre        | New York City | NY         |      2629 |   828981.00
Charles Playhouse       | Boston        | MA         |      2502 |   857031.00
Ethel Barrymore Theatre | New York City | NY         |      2828 |   891172.00
Eugene O'Neill Theatre  | New York City | NY         |      2488 |   828950.00
Greek Theatre           | Los Angeles   | CA         |      2445 |   838918.00
Helen Hayes Theatre     | New York City | NY         |      2948 |   978765.00
Hilton Theatre          | New York City | NY         |      2999 |   885686.00
Imperial Theatre        | New York City | NY         |      2702 |   877993.00
Lunt-Fontanne Theatre   | New York City | NY         |      3326 |  1115182.00
Majestic Theatre        | New York City | NY         |      2549 |   894275.00
Nederlander Theatre     | New York City | NY         |      2934 |   936312.00
Pasadena Playhouse      | Pasadena      | CA         |      2739 |   820435.00
Winter Garden Theatre   | New York City | NY         |      2838 |   939257.00
(14 rows)
```

以下两个示例演示基于 WITH 子句子查询的表引用范围的规则。第一个查询运行，但第二个查询失败，并出现意料中的错误。在第一个查询中，主查询的 SELECT 列表中包含 WITH 子句子查询。SELECT 列表中的子查询的 FROM 子句中将引用 WITH 子句定义的表 (HOLIDAYS)：

```
select caldate, sum(pricepaid) as daysales,
(with holidays as (select * from date where holiday ='t')
select sum(pricepaid)
from sales join holidays on sales.dateid=holidays.dateid
where caldate='2008-12-25') as dec25sales
from sales join date on sales.dateid=date.dateid
where caldate in('2008-12-25','2008-12-31')
group by caldate
order by caldate;

caldate   | daysales | dec25sales
-----------+----------+------------
2008-12-25 | 70402.00 |   70402.00
2008-12-31 | 12678.00 |   70402.00
(2 rows)
```

第二个查询失败，因为它尝试在主查询和 SELECT 列表子查询中引用 HOLIDAYS 表。主查询引用超出范围。

```
select caldate, sum(pricepaid) as daysales,
(with holidays as (select * from date where holiday ='t')
select sum(pricepaid)
from sales join holidays on sales.dateid=holidays.dateid
where caldate='2008-12-25') as dec25sales
from sales join holidays on sales.dateid=holidays.dateid
where caldate in('2008-12-25','2008-12-31')
group by caldate
order by caldate;

ERROR:  relation "holidays" does not exist
```

## 示例：递归 CTE
<a name="r_WITH_clause-recursive-cte-example"></a>

以下是递归 CTE 的示例，该示例返回直接或间接向 John 报告的员工。递归查询包含一个 WHERE 子句，用于将递归深度限制为小于 4 个级别。

```
--create and populate the sample table
  create table employee (
  id int,
  name varchar (20),
  manager_id int
  );
  
  insert into employee(id, name, manager_id)  values
(100, 'Carlos', null),
(101, 'John', 100),
(102, 'Jorge', 101),
(103, 'Kwaku', 101),
(110, 'Liu', 101),
(106, 'Mateo', 102),
(110, 'Nikki', 103),
(104, 'Paulo', 103),
(105, 'Richard', 103),
(120, 'Saanvi', 104),
(200, 'Shirley', 104),
(201, 'Sofía', 102),
(205, 'Zhang', 104);
  
--run the recursive query
  with recursive john_org(id, name, manager_id, level) as
( select id, name, manager_id, 1 as level
  from employee
  where name = 'John'
  union all
  select e.id, e.name, e.manager_id, level + 1 as next_level
  from employee e, john_org j
  where e.manager_id = j.id and level < 4
  )
 select distinct id, name, manager_id from john_org order by manager_id;
```

以下是查询的结果。

```
    id        name      manager_id
  ------+-----------+--------------
   101    John           100
   102    Jorge          101
   103    Kwaku          101
   110    Liu            101
   201    Sofía          102
   106    Mateo          102
   110    Nikki          103
   104    Paulo          103
   105    Richard        103
   120    Saanvi         104
   200    Shirley        104
   205    Zhang          104
```

以下是 John 所在部门的组织结构图。

![\[John 所在部门的组织结构图。\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/images/org-chart.png)


# SELECT 列表
<a name="r_SELECT_list"></a>

**Topics**
+ [语法](#r_SELECT_list-synopsis)
+ [参数](#r_SELECT_list-parameters)
+ [使用说明](#r_SELECT_list_usage_notes)
+ [示例](#r_SELECT_list-examples)

SELECT 列表指定希望查询返回的列、函数和表达式。列表表示查询的输出。

有关 SQL 函数的更多信息，请参阅 [SQL 函数参考](c_SQL_functions.md)。有关表达式的更多信息，请参阅[条件表达式](c_conditional_expressions.md)。

## 语法
<a name="r_SELECT_list-synopsis"></a>

```
SELECT
[ TOP number ]
[ ALL | DISTINCT ] * | expression [ AS column_alias ] [, ...]
```

## 参数
<a name="r_SELECT_list-parameters"></a>

TOP *number*   
TOP 将正整数用作其参数，用于定义返回到客户端的行数。使用 TOP 子句的行为与使用 LIMIT 子句的行为相同。返回的行数是固定的，但行集不固定。要返回一致的行集，请将 TOP 或 LIMIT 与 ORDER BY 子句结合使用。

ALL   
一个冗余关键字，定义未指定 DISTINCT 的情况下的默认行为。`SELECT ALL *` 与 `SELECT *` 的含义相同（选择所有列的所有行并保留重复条目）。

DISTINCT   
一个选项，用于根据一个或多个列中的匹配值消除结果集中的重复行。  
如果您的应用程序允许无效的外键或主键，则会导致查询返回错误的结果。例如，如果主键列不包含所有唯一值，则 SELECT DISTINCT 查询可能会返回重复的行。有关更多信息，请参阅[定义表约束](https://docs.aws.amazon.com/redshift/latest/dg/t_Defining_constraints.html)。

\$1（星号）   
返回表的完整内容（所有列和所有行）。

 *expression*   
由查询引用的表中存在的一个或多个列构成的表达式。表达式可包含 SQL 函数。例如：  

```
avg(datediff(day, listtime, saletime))
```

AS *column\$1alias*   
在最终结果集中使用的列的临时名称。AS 关键字是可选的。例如：  

```
avg(datediff(day, listtime, saletime)) as avgwait
```
如果您没有为不是简单列名的表达式指定别名，则结果集将对该列应用默认名称。  
在目标列表中定义别名后，它将立即被识别。您可以在其他表达式中使用在同一目标列表中晚于该别名定义的某个别名。以下示例对此进行了说明。  

```
select clicks / impressions as probability, round(100 * probability, 1) as percentage from raw_data;
```
横向别名引用的好处是，当在同一目标列表中构建更复杂的表达式时，不需要重复已指定别名的表达式。当 Amazon Redshift 分析这种类型的引用时，它只会内联之前定义的别名。如果在 `FROM` 子句中定义了一个与之前指定了别名的表达式同名的列，`FROM` 子句中定义的列将优先。例如，在上述查询中，如果表 raw\$1data 中有一个名为“probability”的列，那么目标列表中的第二个表达式中的“probability”引用该列而不是别名“probability”。

## 使用说明
<a name="r_SELECT_list_usage_notes"></a>

TOP 是一个 SQL 扩展；它提供 LIMIT 行为的替代。不能在同一个查询中使用 TOP 和 LIMIT。

## 示例
<a name="r_SELECT_list-examples"></a>

以下示例从 SALES 表中返回 10 行。尽管查询使用 TOP 子句，但它仍然返回一组不可预测的行，因为没有指定 ORDERBY 子句，

```
select top 10 *
from sales;
```

以下查询具有相同的功能，但使用的是 LIMIT 子句而非 TOP 子句：

```
select *
from sales
limit 10;
```

以下示例使用 TOP 子句返回 SALES 表的前 10 行，按 QTYSOLD 列降序排序。

```
select top 10 qtysold, sellerid
from sales
order by qtysold desc, sellerid;

qtysold | sellerid
--------+----------
8 |      518
8 |      520
8 |      574
8 |      718
8 |      868
8 |     2663
8 |     3396
8 |     3726
8 |     5250
8 |     6216
(10 rows)
```

以下示例返回 SALES 表中的前两个 QTYSOLD 和 SELLERID 值（按 QTYSOLD 列排序）：

```
select top 2 qtysold, sellerid
from sales
order by qtysold desc, sellerid;

qtysold | sellerid
--------+----------
8 |      518
8 |      520
(2 rows)
```

以下示例显示 CATEGORY 表中不同类别组的列表：

```
select distinct catgroup from category
order by 1;

catgroup
----------
Concerts
Shows
Sports
(3 rows)

--the same query, run without distinct
select catgroup from category
order by 1;

catgroup
----------
Concerts
Concerts
Concerts
Shows
Shows
Shows
Sports
Sports
Sports
Sports
Sports
(11 rows)
```

以下示例返回 2008 年 12 月的一组不同的周编号。如果没有 DISTINCT 子句，该语句将返回 31 行，或对于月份的每一天返回 1 行。

```
select distinct week, month, year
from date
where month='DEC' and year=2008
order by 1, 2, 3;

week | month | year
-----+-------+------
49 | DEC   | 2008
50 | DEC   | 2008
51 | DEC   | 2008
52 | DEC   | 2008
53 | DEC   | 2008
(5 rows)
```



# EXCLUDE column\$1list
<a name="r_EXCLUDE_list"></a>

EXCLUDE column\$1list 对从查询结果中排除的列进行命名。当只需从*宽* 表（包含许多列的表）中排除一部分列时，使用 EXCLUDE 选项会很有用。

**Topics**
+ [语法](#r_EXCLUDE_list-synopsis)
+ [参数](#r_EXCLUDE_list-parameters)
+ [示例](#r_EXCLUDE_list-examples)

## 语法
<a name="r_EXCLUDE_list-synopsis"></a>

```
EXCLUDE column_list
```

## 参数
<a name="r_EXCLUDE_list-parameters"></a>

 *column\$1list*   
查询引用的表中存在的一个或多个列名称的逗号分隔列表。*column\$1list* 可以选择用括号括起来。列名称的排除列表中仅支持列名称，而不支持表达式（例如 `upper(col1)`）或星号（\$1）。  

```
column-name, ... | ( column-name, ... )
```
例如：  

```
SELECT * EXCLUDE col1, col2 FROM tablea;
```

```
SELECT * EXCLUDE (col1, col2) FROM tablea;
```

## 示例
<a name="r_EXCLUDE_list-examples"></a>

下面的示例使用包含以下各列的 SALES 表：salesid、listid、sellerid、buyerid、eventid、dateid、qtysold、pricepaid、commission 和 saletime。有关 SALES 表的更多信息，请参阅[示例数据库](c_sampledb.md)。

以下示例返回 SALES 表中的行，但不包括 SALETIME 列。

```
SELECT * EXCLUDE saletime FROM sales;

salesid | listid  | sellerid | buyerid | eventid | dateid  | qtysold  | pricepaid  | commission
--------+---------+----------+---------+---------+---------+----------+------------+-----------
150314  | 173969  | 48680    | 816     | 8762    | 1827    | 2        | 688        | 103.2	
8325    | 8942    | 23600    | 1078    | 2557    | 1828    | 5        | 525        |  78.75	
46807   | 52711   | 34388    | 1047    | 2046    | 1828    | 2        | 482        |  72.3	
...
```

以下示例返回 SALES 表中的行，但不包括 QTYSOLD 和 SALETIME 列。

```
SELECT * EXCLUDE (qtysold, saletime) FROM sales;

salesid | listid  | sellerid | buyerid | eventid | dateid  | pricepaid  | commission
--------+---------+----------+---------+---------+---------+------------+-----------
150314  | 173969  | 48680    | 816     | 8762    | 1827    | 688        | 103.2	
8325    | 8942    | 23600    | 1078    | 2557    | 1828    | 525        |  78.75	
46807   | 52711   | 34388    | 1047    | 2046    | 1828    | 482        |  72.3	
...
```

以下示例创建了一个视图，该视图返回 SALES 表中的行，但不包括 SALETIME 列。

```
CREATE VIEW sales_view AS SELECT * EXCLUDE saletime FROM sales;
SELECT * FROM sales_view;

salesid | listid  | sellerid | buyerid | eventid | dateid  | qtysold  | pricepaid  | commission
--------+---------+----------+---------+---------+---------+----------+------------+-----------
150314  | 173969  | 48680    | 816     | 8762    | 1827    | 2        | 688        | 103.2	
8325    | 8942    | 23600    | 1078    | 2557    | 1828    | 5        | 525        |  78.75	
46807   | 52711   | 34388    | 1047    | 2046    | 1828    | 2        | 482        |  72.3	
...
```

以下示例仅选择未排除到临时表中的列。

```
SELECT * EXCLUDE saletime INTO TEMP temp_sales FROM sales;
SELECT * FROM temp_sales;

salesid | listid  | sellerid | buyerid | eventid | dateid  | qtysold  | pricepaid  | commission
--------+---------+----------+---------+---------+---------+----------+------------+-----------
150314  | 173969  | 48680    | 816     | 8762    | 1827    | 2        | 688        | 103.2	
8325    | 8942    | 23600    | 1078    | 2557    | 1828    | 5        | 525        |  78.75	
46807   | 52711   | 34388    | 1047    | 2046    | 1828    | 2        | 482        |  72.3	
...
```

# FROM 子句
<a name="r_FROM_clause30"></a>

查询中的 FROM 子句列出从中选择数据的表引用（表、视图和子查询）。如果列出多个表引用，则必须在 FROM 子句或 WHERE 子句中使用适当的语法来联接表。如果未指定联接条件，则系统将查询作为交叉联接（笛卡尔乘积）进行处理。

**Topics**
+ [语法](#r_FROM_clause30-synopsis)
+ [参数](#r_FROM_clause30-parameters)
+ [使用说明](#r_FROM_clause_usage_notes)
+ [PIVOT 和 UNPIVOT 示例](r_FROM_clause-pivot-unpivot-examples.md)
+ [JOIN 示例](r_Join_examples.md)
+ [UNNEST 示例](r_FROM_clause-unnest-examples.md)

## 语法
<a name="r_FROM_clause30-synopsis"></a>

```
FROM table_reference [, ...]
```

其中，*table\$1reference* 是下列项之一：

```
with_subquery_table_name [ table_alias ]
table_name [ * ] [ table_alias ]
( subquery ) [ table_alias ]
table_reference [ NATURAL ] join_type table_reference
   [ ON join_condition | USING ( join_column [, ...] ) ]
table_reference  join_type super_expression 
   [ ON join_condition ]
table_reference PIVOT ( 
   aggregate(expr) [ [ AS ] aggregate_alias ]
   FOR column_name IN ( expression [ AS ] in_alias [, ...] )
) [ table_alias ]
table_reference UNPIVOT [ INCLUDE NULLS | EXCLUDE NULLS ] ( 
   value_column_name 
   FOR name_column_name IN ( column_reference [ [ AS ]
   in_alias ] [, ...] )
) [ table_alias ]
UNPIVOT expression AS value_alias [ AT attribute_alias ]
( super_expression.attribute_name ) AS value_alias [ AT index_alias ]
UNNEST ( column_reference )
  [AS] table_alias ( unnested_column_name )
UNNEST ( column_reference ) WITH OFFSET
  [AS] table_alias ( unnested_column_name, [offset_column_name] )
```

可选的 *table\$1alias* 可用于为表和复杂表引用指定临时名称，如果需要，也可以为其列指定临时名称，如下所示：

```
[ AS ] alias [ ( column_alias [, ...] ) ]
```

## 参数
<a name="r_FROM_clause30-parameters"></a>

 *with\$1subquery\$1table\$1name*   
[WITH 子句](r_WITH_clause.md)中的子查询定义的表。

 *table\$1name*   
表或视图的名称。

 *alias*   
表或视图的临时备用名称。必须为派生自子查询的表提供别名。在其他表引用中，别名是可选的。AS 关键字始终是可选的。表别名提供了用于标识查询的其他部分（例如 WHERE 子句）中的表的快捷方法。例如：  

```
select * from sales s, listing l
where s.listid=l.listid
```

 *column\$1alias*   
表或视图中的列的临时备用名称。

 *subquery*   
一个计算结果为表的查询表达式。表仅在查询的持续时间内存在，并且通常会向表提供一个名称或*别名*。但别名不是必需的。您也可以为派生自子查询的表定义列名称。如果您希望将子查询的结果联接到其他表并且希望在查询中的其他位置选择或约束这些列，则指定列的别名是非常重要的。  
子查询可以包含 ORDER BY 子句，但在未指定 LIMIT 或 OFFSET 子句的情况下，该子句可能没有任何作用。

NATURAL   
定义一个联接，该联接自动将两个表中同名列的所有配对用作联接列。不需要显式联接条件。例如，如果 CATEGORY 和 EVENT 表都具有名为 CATID 的列，则这两个表的自然联接为基于其 CATID 列的联接。  
如果指定 NATURAL 联接，但表中没有要联接的同名列配对，则查询默认为交叉联接。

 *join\$1type*   
指定下列类型的联接之一：  
+ [INNER] JOIN 
+ LEFT [OUTER] JOIN 
+ RIGHT [OUTER] JOIN 
+ FULL [OUTER] JOIN 
+ CROSS JOIN 
交叉联接是未限定的联接；它们返回两个表的笛卡尔乘积。  
内部联接和外部联接是限定的联接。它们的限定方式包括：隐式（在自然联接中）；在 FROM 语句中使用 ON 或 USING 语法；或者使用 WHERE 子句条件。  
内部联接仅基于联接条件或联接列的列表返回匹配的行。外部联接返回与内部联接相同的所有行，还返回“左侧”表和/或“右侧”表中的非匹配行。左侧表是第一个列出的表，右侧表是第二个列出的表。非匹配行包含 NULL 值以填补输出列中的空白。

ON *join\$1condition*   
联接规范的类型，其中将联接列声明为紧跟 ON 关键字的条件。例如：  

```
sales join listing
on sales.listid=listing.listid and sales.eventid=listing.eventid
```

USING ( *join\$1column* [, ...] )   
联接规范的类型，其中用圆括号将列出的联接列括起来。如果指定多个联接列，则用逗号将它们分隔开。USING 关键字必须在列表之前。例如：  

```
sales join listing
using (listid,eventid)
```

PIVOT  
将输出由行转换为列，以便以易于阅读的格式表示表格数据。在多个列中水平表示输出。PIVOT 类似于带有聚合的 GROUP BY 查询，它使用聚合表达式来指定输出格式。但是，与 GROUP BY 不同的是，它以列而非行的形式返回输出。  
有关演示如何使用 PIVOT 和 UNPIVOT 查询的示例，请参阅 [PIVOT 和 UNPIVOT 示例](r_FROM_clause-pivot-unpivot-examples.md)。

UNPIVOT  
*使用 UNPIVOT 将列旋转为行* – 此运算符将输入表或查询结果中的结果列转换为行，以使输出更易于阅读。UNPIVOT 将其输入列的数据合并为两个结果列：名称列和值列。名称列包含输入中的列名称，例如行条目。值列包含输入列中的值，例如聚合结果。例如，不同类别中的项目计数。  
*使用 UNPIVOT (SUPER) 反转置对象* - 您可以执行对象反转置，其中 *expression* 是引用另一个 FROM 子句项的 SUPER 表达式。有关更多信息，请参阅 [对象逆透视](query-super.md#unpivoting)。它还提供了一些示例，展示如何查询半结构化数据，例如 JSON 格式的数据。

*super\$1expression*  
有效的 SUPER 表达式。Amazon Redshift 会为指定属性中的每个值返回一行。有关 SUPER 数据类型的更多信息，请参阅 [SUPER 类型](r_SUPER_type.md)。有关取消嵌套的 SUPER 值的更多信息，请参阅[取消嵌套查询](query-super.md#unnest)。

*attribute\$1name*  
SUPER 表达式中属性的名称。

*index\$1alias*  
表示值在 SUPER 表达式中位置的索引的别名。

UNNEST  
将嵌套结构（通常是 SUPER 数组）扩展为包含取消嵌套元素的列。有关取消嵌套 SUPER 数据的更多信息，请参阅[查询半结构化数据](query-super.md)。有关示例，请参阅 [UNNEST 示例](r_FROM_clause-unnest-examples.md)。

*unnested\$1column\$1name*  
包含取消嵌套元素的列的名称。

UNNEST ... WITH OFFSET  
将偏移列添加到取消嵌套的输出中，偏移表示数组中每个元素从零开始的索引。当您想要查看数组中元素的位置时，这个变量很有用。有关取消嵌套 SUPER 数据的更多信息，请参阅[查询半结构化数据](query-super.md)。有关示例，请参阅 [UNNEST 示例](r_FROM_clause-unnest-examples.md)。

*offset\$1column\$1name*  
偏移列的自定义名称，可让您显式定义索引列将在输出中的显示方式。此参数为可选的。默认情况下，偏移列的名称为 `offset_col`。

## 使用说明
<a name="r_FROM_clause_usage_notes"></a>

联接列必须具有可比较的数据类型。

NATURAL 或 USING 联接仅将每对联接列中的一个联接列保留在中间结果集中。

使用 ON 语法的联接会将两个联接列都保留在其中间结果集中。

另请参阅 [WITH 子句](r_WITH_clause.md)。

# PIVOT 和 UNPIVOT 示例
<a name="r_FROM_clause-pivot-unpivot-examples"></a>

PIVOT 和 UNPIVOT 是 FROM 子句中的参数，它们分别将查询输出从行轮换到列，以及从列轮换到行。它们以便于阅读的格式呈现表格查询结果。以下示例使用测试数据和查询来说明如何使用它们。

有关这些参数及其他参数的更多信息，请参阅 [FROM 子句](https://docs.aws.amazon.com/redshift/latest/dg/r_FROM_clause30.html)。

## PIVOT 示例
<a name="r_FROM_clause-pivot-examples"></a>

设置示例表和数据并使用它们运行后续示例查询。

```
CREATE TABLE part (
    partname varchar,
    manufacturer varchar,
    quality int,
    price decimal(12, 2)
);

INSERT INTO part VALUES ('prop', 'local parts co', 2, 10.00);
INSERT INTO part VALUES ('prop', 'big parts co', NULL, 9.00);
INSERT INTO part VALUES ('prop', 'small parts co', 1, 12.00);

INSERT INTO part VALUES ('rudder', 'local parts co', 1, 2.50);
INSERT INTO part VALUES ('rudder', 'big parts co', 2, 3.75);
INSERT INTO part VALUES ('rudder', 'small parts co', NULL, 1.90);

INSERT INTO part VALUES ('wing', 'local parts co', NULL, 7.50);
INSERT INTO part VALUES ('wing', 'big parts co', 1, 15.20);
INSERT INTO part VALUES ('wing', 'small parts co', NULL, 11.80);
```

`partname` 上的 PIVOT，在 `price` 上有一个 `AVG` 聚合。

```
SELECT *
FROM (SELECT partname, price FROM part) PIVOT (
    AVG(price) FOR partname IN ('prop', 'rudder', 'wing')
);
```

查询将生成以下输出。

```
  prop   |  rudder  |  wing
---------+----------+---------
 10.33   | 2.71     | 11.50
```

在前面的示例中，结果转换为列。以下示例显示了一个按行而不是按列返回平均价格的 `GROUP BY` 查询。

```
SELECT partname, avg(price)
FROM (SELECT partname, price FROM part)
WHERE partname IN ('prop', 'rudder', 'wing')
GROUP BY partname;
```

查询将生成以下输出。

```
 partname |  avg
----------+-------
 prop     | 10.33
 rudder   |  2.71
 wing     | 11.50
```

一个 `PIVOT` 示例，将 `manufacturer` 作为隐式列。

```
SELECT *
FROM (SELECT quality, manufacturer FROM part) PIVOT (
    count(*) FOR quality IN (1, 2, NULL)
);
```

查询将生成以下输出。

```
 manufacturer      | 1  | 2  | null
-------------------+----+----+------
 local parts co    | 1  | 1  |  1
 big parts co      | 1  | 1  |  1
 small parts co    | 1  | 0  |  2
```

 `PIVOT` 定义中未引用的输入表列被隐式添加到结果表中。就是上一个示例中 `manufacturer` 列这种情况。示例还显示，对于 `IN` 运算符，`NULL` 为有效值。

`PIVOT`上述示例中的 返回与以下查询类似的信息，其中包含 `GROUP BY`。区别在于 `PIVOT` 为列 `2` 和 制造商 `small parts co` 返回值 `0`。`GROUP BY` 查询不包含相应的行。在大多数情况下，如果一行没有针对给定列的输入数据，则 `PIVOT` 会插入 `NULL`。但是，计数聚合不会返回 `NULL`，`0` 是默认值。

```
SELECT manufacturer, quality, count(*)
FROM (SELECT quality, manufacturer FROM part)
WHERE quality IN (1, 2) OR quality IS NULL
GROUP BY manufacturer, quality
ORDER BY manufacturer;
```

查询将生成以下输出。

```
 manufacturer        | quality | count
---------------------+---------+-------
 big parts co        |         |     1
 big parts co        |       2 |     1
 big parts co        |       1 |     1
 local parts co      |       2 |     1
 local parts co      |       1 |     1
 local parts co      |         |     1
 small parts co      |       1 |     1
 small parts co      |         |     2
```

 PIVOT 运算符接受聚合表达式和 `IN` 运算符的每个值上的可选别名。使用别名自定义列名。如果没有聚合别名，则仅使用 `IN` 列表别名。否则，将聚合别名附加到列名，并使用下划线将其与列名分开。

```
SELECT *
FROM (SELECT quality, manufacturer FROM part) PIVOT (
    count(*) AS count FOR quality IN (1 AS high, 2 AS low, NULL AS na)
);
```

查询将生成以下输出。

```
 manufacturer      | high_count  | low_count | na_count
-------------------+-------------+-----------+----------
 local parts co    |           1 |         1 |        1
 big parts co      |           1 |         1 |        1
 small parts co    |           1 |         0 |        2
```

设置以下示例表和数据，并使用它们运行后续示例查询。该数据表示一系列酒店的预订日期。

```
CREATE TABLE bookings (
    booking_id int,
    hotel_code char(8),
    booking_date date,
    price decimal(12, 2)
);

INSERT INTO bookings VALUES (1, 'FOREST_L', '02/01/2023', 75.12);
INSERT INTO bookings VALUES (2, 'FOREST_L', '02/02/2023', 75.00);
INSERT INTO bookings VALUES (3, 'FOREST_L', '02/04/2023', 85.54);

INSERT INTO bookings VALUES (4, 'FOREST_L', '02/08/2023', 75.00);
INSERT INTO bookings VALUES (5, 'FOREST_L', '02/11/2023', 75.00);
INSERT INTO bookings VALUES (6, 'FOREST_L', '02/14/2023', 90.00);

INSERT INTO bookings VALUES (7, 'FOREST_L', '02/21/2023', 60.00);
INSERT INTO bookings VALUES (8, 'FOREST_L', '02/22/2023', 85.00);
INSERT INTO bookings VALUES (9, 'FOREST_L', '02/27/2023', 90.00);

INSERT INTO bookings VALUES (10, 'DESERT_S', '02/01/2023', 98.00);
INSERT INTO bookings VALUES (11, 'DESERT_S', '02/02/2023', 75.00);
INSERT INTO bookings VALUES (12, 'DESERT_S', '02/04/2023', 85.00);

INSERT INTO bookings VALUES (13, 'DESERT_S', '02/05/2023', 75.00);
INSERT INTO bookings VALUES (14, 'DESERT_S', '02/06/2023', 34.00);
INSERT INTO bookings VALUES (15, 'DESERT_S', '02/09/2023', 85.00);

INSERT INTO bookings VALUES (16, 'DESERT_S', '02/12/2023', 23.00);
INSERT INTO bookings VALUES (17, 'DESERT_S', '02/13/2023', 76.00);
INSERT INTO bookings VALUES (18, 'DESERT_S', '02/14/2023', 85.00);

INSERT INTO bookings VALUES (19, 'OCEAN_WV', '02/01/2023', 98.00);
INSERT INTO bookings VALUES (20, 'OCEAN_WV', '02/02/2023', 75.00);
INSERT INTO bookings VALUES (21, 'OCEAN_WV', '02/04/2023', 85.00);

INSERT INTO bookings VALUES (22, 'OCEAN_WV', '02/06/2023', 75.00);
INSERT INTO bookings VALUES (23, 'OCEAN_WV', '02/09/2023', 34.00);
INSERT INTO bookings VALUES (24, 'OCEAN_WV', '02/12/2023', 85.00);

INSERT INTO bookings VALUES (25, 'OCEAN_WV', '02/13/2023', 23.00);
INSERT INTO bookings VALUES (26, 'OCEAN_WV', '02/14/2023', 76.00);
INSERT INTO bookings VALUES (27, 'OCEAN_WV', '02/16/2023', 85.00);

INSERT INTO bookings VALUES (28, 'CITY_BLD', '02/01/2023', 98.00);
INSERT INTO bookings VALUES (29, 'CITY_BLD', '02/02/2023', 75.00);
INSERT INTO bookings VALUES (30, 'CITY_BLD', '02/04/2023', 85.00);

INSERT INTO bookings VALUES (31, 'CITY_BLD', '02/12/2023', 75.00);
INSERT INTO bookings VALUES (32, 'CITY_BLD', '02/13/2023', 34.00);
INSERT INTO bookings VALUES (33, 'CITY_BLD', '02/17/2023', 85.00);

INSERT INTO bookings VALUES (34, 'CITY_BLD', '02/22/2023', 23.00);
INSERT INTO bookings VALUES (35, 'CITY_BLD', '02/23/2023', 76.00);
INSERT INTO bookings VALUES (36, 'CITY_BLD', '02/24/2023', 85.00);
```

 在此示例查询中，对预订记录进行统计以得出每周的总数。每周的结束日期成为列名。

```
SELECT * FROM
    (SELECT
       booking_id,
       (date_trunc('week', booking_date::date) + '5 days'::interval)::date as enddate,
       hotel_code AS "hotel code"
FROM bookings
) PIVOT (
    count(booking_id) FOR enddate IN ('2023-02-04','2023-02-11','2023-02-18') 
);
```

查询将生成以下输出。

```
 hotel code | 2023-02-04  | 2023-02-11 | 2023-02-18
------------+-------------+------------+----------
 FOREST_L   |           3 |          2 |        1
 DESERT_S   |           4 |          3 |        2
 OCEAN_WV   |           3 |          3 |        3
 CITY_BLD   |           3 |          1 |        2
```

 Amazon Redshift 不支持 CROSSTAB 对多列进行透视。但您可以将行数据更改为列，与使用 PIVOT 进行聚合类似，使用如下所示的查询。这使用与上一个示例相同的预订示例数据。

```
SELECT 
  booking_date,
  MAX(CASE WHEN hotel_code = 'FOREST_L' THEN 'forest is booked' ELSE '' END) AS FOREST_L,
  MAX(CASE WHEN hotel_code = 'DESERT_S' THEN 'desert is booked' ELSE '' END) AS DESERT_S,
  MAX(CASE WHEN hotel_code = 'OCEAN_WV' THEN 'ocean is booked' ELSE '' END)  AS OCEAN_WV
FROM bookings
GROUP BY booking_date
ORDER BY booking_date asc;
```

示例查询会导致在表示已预订了哪些酒店的短语旁边列出预订日期。

```
 booking_date  | forest_l         | desert_s         | ocean_wv
---------------+------------------+------------------+--------------------
 2023-02-01    | forest is booked | desert is booked |  ocean is booked
 2023-02-02    | forest is booked | desert is booked |  ocean is booked
 2023-02-04    | forest is booked | desert is booked |  ocean is booked
 2023-02-05    |                  | desert is booked |        
 2023-02-06    |                  | desert is booked |
```

以下是 `PIVOT` 的使用说明：
+ `PIVOT` 可以应用于表、子查询和公用表表达式（CTE）。`PIVOT` 不可应用于任何 `JOIN` 表达式、递归 CTE、`PIVOT` 或 `UNPIVOT` 表达式。此外，也不支持 `SUPER` 取消嵌套的表达式和 Redshift Spectrum 嵌套表。
+  `PIVOT` 支持 `COUNT`、`SUM`、`MIN`、`MAX` 和 `AVG` 聚合函数。
+ `PIVOT` 聚合表达式必须是对受支持的聚合函数的调用。不支持聚合顶部的复杂表达式。聚合参数仅可包含对 `PIVOT` 输入表的引用。此外，也不支持对父查询的关联引用。聚合参数可能包含子查询。它们可以在内部关联或在 `PIVOT` 输入表上关联。
+  `PIVOT IN` 列表值不得为列引用或子查询。每个值必须与 `FOR` 列引用类型兼容。
+  如果 `IN` 列表值没有别名，`PIVOT` 会生成默认的列名。对于常量 `IN` 值（例如“abc”或 5），默认列名是常量本身。对于任何复杂表达式，列名都是标准的 Amazon Redshift 默认名称，例如 `?column?`。

## UNPIVOT 示例
<a name="r_FROM_clause-unpivot-examples"></a>

设置示例数据并使用它来运行后续示例。

```
CREATE TABLE count_by_color (quality varchar, red int, green int, blue int);

INSERT INTO count_by_color VALUES ('high', 15, 20, 7);
INSERT INTO count_by_color VALUES ('normal', 35, NULL, 40);
INSERT INTO count_by_color VALUES ('low', 10, 23, NULL);
```

`UNPIVOT`红、绿和蓝输入列上的 。

```
SELECT *
FROM (SELECT red, green, blue FROM count_by_color) UNPIVOT (
    cnt FOR color IN (red, green, blue)
);
```

查询将生成以下输出。

```
 color | cnt
-------+-----
 red   |  15
 red   |  35
 red   |  10
 green |  20
 green |  23
 blue  |   7
 blue  |  40
```

默认情况下，将跳过输入列中的 `NULL` 值，且不会产生结果行。

以下示例显示了带有 `INCLUDE NULLS` 的 `UNPIVOT`。

```
SELECT *
FROM (
    SELECT red, green, blue
    FROM count_by_color
) UNPIVOT INCLUDE NULLS (
    cnt FOR color IN (red, green, blue)
);
```

以下是结果输出。

```
 color | cnt
-------+-----
 red   |  15
 red   |  35
 red   |  10
 green |  20
 green |
 green |  23
 blue  |   7
 blue  |  40
 blue  |
```

如果已设置 `INCLUDING NULLS` 参数，`NULL` 输入值将生成结果行。

带有 `quality` 的 `The following query shows UNPIVOT` 作为隐式列。

```
SELECT *
FROM count_by_color UNPIVOT (
    cnt FOR color IN (red, green, blue)
);
```

查询将生成以下输出。

```
 quality | color | cnt
---------+-------+-----
 high    | red   |  15
 normal  | red   |  35
 low     | red   |  10
 high    | green |  20
 low     | green |  23
 high    | blue  |   7
 normal  | blue  |  40
```

`UNPIVOT` 定义中未引用的输入表列被隐式添加到结果表中。在该示例中，`quality` 列就是这种情况。

以下示例显示了带有 `UNPIVOT` 列表中值别名的 `IN`。

```
SELECT *
FROM count_by_color UNPIVOT (
    cnt FOR color IN (red AS r, green AS g, blue AS b)
);
```

上一查询将产生以下输出。

```
 quality | color | cnt
---------+-------+-----
 high    | r     |  15
 normal  | r     |  35
 low     | r     |  10
 high    | g     |  20
 low     | g     |  23
 high    | b     |   7
 normal  | b     |  40
```

`UNPIVOT` 运算符接受每个 `IN` 列表值上的可选别名。每个别名会提供每个 `value` 列中的数据自定义。

以下是 `UNPIVOT` 的使用说明。
+ `UNPIVOT` 可以应用于表、子查询和公用表表达式（CTE）。`UNPIVOT` 不可应用于任何 `JOIN` 表达式、递归 CTE、`PIVOT` 或 `UNPIVOT` 表达式。此外，也不支持 `SUPER` 取消嵌套的表达式和 Redshift Spectrum 嵌套表。
+ `UNPIVOT IN` 列表必须仅包含输入表列引用。`IN` 列表列必须具有它们都与之兼容的常见类型。`UNPIVOT` 值列具有这一常见类型。`UNPIVOT` 名称列属于类型 `VARCHAR`。
+ 如果 `IN` 列表值没有别名，`UNPIVOT` 则使用列名作为默认值。

# JOIN 示例
<a name="r_Join_examples"></a>

SQL JOIN 子句用于根据公共字段合并两个或多个表中的数据。根据指定的联接方法，结果可能会发生变化，也可能不发生变化。有关 JOIN 子句的语法的更多信息，请参阅[参数](r_FROM_clause30.md#r_FROM_clause30-parameters)。

以下示例使用 `TICKIT` 示例数据中的数据。有关数据库架构的更多信息，请参阅[示例数据库](c_sampledb.md)。要了解如何加载示例数据，请参阅《Amazon Redshift 入门指南》**中的[加载数据](https://docs.aws.amazon.com/redshift/latest/gsg/rs-gsg-create-sample-db.html)。

下面的查询是 LISTING 表和 SALES 表之间的内部联接（不带 JOIN 关键字），其中 LISTING 表中的 LISTID 介于 1 和 5 之间。此查询匹配 LISTING 表（左表）和 SALES 表（右表）中的 LISTID 列值。结果显示 LISTID 1、4 和 5 符合条件。

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from listing, sales
where listing.listid = sales.listid
and listing.listid between 1 and 5
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     1 | 728.00 | 109.20
     4 |  76.00 |  11.40
     5 | 525.00 |  78.75
```

以下查询是一个左外部联接。当在其他表中找不到匹配项时，左外部联接和右外部联接保留某个已联接表中的值。左表和右表是语法中列出的第一个表和第二个表。NULL 值用于填补结果集中的“空白”。此查询匹配 LISTING 表（左表）和 SALES 表（右表）中的 LISTID 列值。结果表明 LISTID 2 和 3 不会生成任何销售额。

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from listing left outer join sales on sales.listid = listing.listid
where listing.listid between 1 and 5
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     1 | 728.00 | 109.20
     2 | NULL   | NULL
     3 | NULL   | NULL
     4 |  76.00 |  11.40
     5 | 525.00 |  78.75
```

以下查询是一个右外部联接。此查询匹配 LISTING 表（左表）和 SALES 表（右表）中的 LISTID 列值。结果显示 ListID 1、4 和 5 符合条件。

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from listing right outer join sales on sales.listid = listing.listid
where listing.listid between 1 and 5
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     1 | 728.00 | 109.20
     4 |  76.00 |  11.40
     5 | 525.00 |  78.75
```

以下查询是一个完全联接。当在其他表中找不到匹配项时，完全联接保留已联接表中的值。左表和右表是语法中列出的第一个表和第二个表。NULL 值用于填补结果集中的“空白”。此查询匹配 LISTING 表（左表）和 SALES 表（右表）中的 LISTID 列值。结果表明 LISTID 2 和 3 不会生成任何销售额。

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from listing full join sales on sales.listid = listing.listid
where listing.listid between 1 and 5
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     1 | 728.00 | 109.20
     2 | NULL   | NULL
     3 | NULL   | NULL
     4 |  76.00 |  11.40
     5 | 525.00 |  78.75
```

以下查询是一个完全联接。此查询匹配 LISTING 表（左表）和 SALES 表（右表）中的 LISTID 列值。结果中只有不会导致任何销售额的行（ListID 2 和 3）。

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from listing full join sales on sales.listid = listing.listid
where listing.listid between 1 and 5
and (listing.listid IS NULL or sales.listid IS NULL)
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     2 | NULL   | NULL
     3 | NULL   | NULL
```

以下示例是与 ON 子句的内部联接。在这种情况下，不返回 NULL 行。

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from sales join listing
on sales.listid=listing.listid and sales.eventid=listing.eventid
where listing.listid between 1 and 5
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     1 | 728.00 | 109.20
     4 |  76.00 |  11.40
     5 | 525.00 |  78.75
```

以下查询是 LISTING 表和 SALES 表的交叉联接或笛卡尔联接，其中包含限制结果的谓词。此查询匹配 SALES 表和 LISTING 表中的 LISTID 列值，对应于这两个表中的 LISTID 1、2、3、4 和 5。结果显示 20 个行符合条件。

```
select sales.listid as sales_listid, listing.listid as listing_listid
from sales cross join listing
where sales.listid between 1 and 5
and listing.listid between 1 and 5
order by 1,2;

sales_listid | listing_listid
-------------+---------------
1            | 1
1            | 2
1            | 3
1            | 4
1            | 5
4            | 1
4            | 2
4            | 3
4            | 4
4            | 5
5            | 1
5            | 1
5            | 2
5            | 2
5            | 3
5            | 3
5            | 4
5            | 4
5            | 5
5            | 5
```

以下示例是两个表之间的自然联接。在这种情况下，列 listid、sellerid、eventid 和 dateid 在两个表中具有相同的名称和数据类型，因此用作联接列。结果限制为 5 行。

```
select listid, sellerid, eventid, dateid, numtickets
from listing natural join sales
order by 1
limit 5;

listid | sellerid  | eventid | dateid | numtickets
-------+-----------+---------+--------+-----------
113    | 29704     | 4699    | 2075   | 22
115    | 39115     | 3513    | 2062   | 14
116    | 43314     | 8675    | 1910   | 28
118    | 6079      | 1611    | 1862   | 9
163    | 24880     | 8253    | 1888   | 14
```

以下示例是使用 USING 子句在两个表之间进行的联接。在这种情况下，列 listid 和 eventid 用作联接列。结果限制为 5 行。

```
select listid, listing.sellerid, eventid, listing.dateid, numtickets
from listing join sales
using (listid, eventid)
order by 1
limit 5;

listid | sellerid | eventid | dateid | numtickets
-------+----------+---------+--------+-----------
1      | 36861    | 7872    | 1850   | 10
4      | 8117     | 4337    | 1970   | 8
5      | 1616     | 8647    | 1963   | 4
5      | 1616     | 8647    | 1963   | 4
6      | 47402    | 8240    | 2053   | 18
```

以下查询是 FROM 子句中的两个子查询的内部联接。此查询查找不同类别的活动（音乐会和演出）的已售门票数和未售门票数：这些 FROM 子句子查询是*表* 子查询；它们可返回多个列和行。

```
select catgroup1, sold, unsold
from
(select catgroup, sum(qtysold) as sold
from category c, event e, sales s
where c.catid = e.catid and e.eventid = s.eventid
group by catgroup) as a(catgroup1, sold)
join
(select catgroup, sum(numtickets)-sum(qtysold) as unsold
from category c, event e, sales s, listing l
where c.catid = e.catid and e.eventid = s.eventid
and s.listid = l.listid
group by catgroup) as b(catgroup2, unsold)

on a.catgroup1 = b.catgroup2
order by 1;

catgroup1 |  sold  | unsold
----------+--------+--------
Concerts  | 195444 |1067199
Shows     | 149905 | 817736
```

# UNNEST 示例
<a name="r_FROM_clause-unnest-examples"></a>

UNNEST 是 FROM 子句中的一个参数，用于将嵌套数据扩展为包含数据的取消嵌套元素的列。有关取消嵌套数据的信息，请参阅[查询半结构化数据](query-super.md)。

以下语句创建并填充 `orders` 表，该表包含 `products` 列，其中包含产品 ID 的数组。本节中的示例使用此表中的示例数据。

```
CREATE TABLE orders (
    order_id INT,
    products SUPER
);

-- Populate table
INSERT INTO orders VALUES
(1001, JSON_PARSE('[
        {
            "product_id": "P456",
            "name": "Monitor",
            "price": 299.99,
            "quantity": 1,
            "specs": {
                "size": "27 inch",
                "resolution": "4K"
            }
        }
    ]
')),
(1002, JSON_PARSE('
    [
        {
            "product_id": "P567",
            "name": "USB Cable",
            "price": 9.99,
            "quantity": 3
        },
        {
            "product_id": "P678",
            "name": "Headphones",
            "price": 159.99,
            "quantity": 1,
            "specs": {
                "type": "Wireless",
                "battery_life": "20 hours"
            }
        }
    ]
'));
```

以下是一些使用 PartiQL 语法对示例数据取消嵌套查询的示例。

## 取消嵌套一个没有 OFFSET 列的数组
<a name="r_FROM_clause-unnest-examples-no-offset"></a>

以下查询取消嵌套 products 列中的 SUPER 数组，每行代表订单 `order_id` 中内的一个项目。

```
SELECT o.order_id, unnested_products.product
FROM orders o, UNNEST(o.products) AS unnested_products(product);

 order_id |                                                           product                                                           
----------+-----------------------------------------------------------------------------------------------------------------------------
     1001 | {"product_id":"P456","name":"Monitor","price":299.99,"quantity":1,"specs":{"size":"27 inch","resolution":"4K"}}
     1002 | {"product_id":"P567","name":"USB Cable","price":9.99,"quantity":3}
     1002 | {"product_id":"P678","name":"Headphones","price":159.99,"quantity":1,"specs":{"type":"Wireless","battery_life":"20 hours"}}
(3 rows)
```

以下查询查找每个订单中最昂贵的产品。

```
SELECT o.order_id, MAX(unnested_products.product)
FROM orders o, UNNEST(o.products) AS unnested_products(product);

 order_id |                                                           product                                                           
----------+-----------------------------------------------------------------------------------------------------------------------------
     1001 | {"product_id":"P456","name":"Monitor","price":299.99,"quantity":1,"specs":{"size":"27 inch","resolution":"4K"}}
     1002 | {"product_id":"P678","name":"Headphones","price":159.99,"quantity":1,"specs":{"type":"Wireless","battery_life":"20 hours"}}
(2 rows)
```

## 取消嵌套带有隐式 OFFSET 列的数组
<a name="r_FROM_clause-unnest-examples-implicit-offset"></a>

以下查询使用 `UNNEST ... WITH OFFSET` 参数来显示每个产品在其订单数组中从零开始的位置。

```
SELECT o.order_id, up.product, up.offset_col
FROM orders o, UNNEST(o.products) WITH OFFSET AS up(product);

 order_id |                                                           product                                                           | offset_col 
----------+-----------------------------------------------------------------------------------------------------------------------------+------------
     1001 | {"product_id":"P456","name":"Monitor","price":299.99,"quantity":1,"specs":{"size":"27 inch","resolution":"4K"}}             |          0
     1002 | {"product_id":"P567","name":"USB Cable","price":9.99,"quantity":3}                                                          |          0
     1002 | {"product_id":"P678","name":"Headphones","price":159.99,"quantity":1,"specs":{"type":"Wireless","battery_life":"20 hours"}} |          1
(3 rows)
```

由于该语句没有为偏移列指定别名，因此 Amazon Redshift 默认将其命名为 `offset_col`。

## 取消嵌套带有显式 OFFSET 列的数组
<a name="r_FROM_clause-unnest-examples-explicit-offset"></a>

以下查询还使用 `UNNEST ... WITH OFFSET` 参数来显示其订单数组中的产品。与上一个示例中的查询相比，此查询的不同之处在于，它使用别名 `idx` 显式命名偏移列。

```
SELECT o.order_id, up.product, up.idx
FROM orders o, UNNEST(o.products) WITH OFFSET AS up(product, idx);

 order_id |                                                           product                                                           | idx 
----------+-----------------------------------------------------------------------------------------------------------------------------+-----
     1001 | {"product_id":"P456","name":"Monitor","price":299.99,"quantity":1,"specs":{"size":"27 inch","resolution":"4K"}}             |   0
     1002 | {"product_id":"P567","name":"USB Cable","price":9.99,"quantity":3}                                                          |   0
     1002 | {"product_id":"P678","name":"Headphones","price":159.99,"quantity":1,"specs":{"type":"Wireless","battery_life":"20 hours"}} |   1
(3 rows)
```

# WHERE 子句
<a name="r_WHERE_clause"></a>

WHERE 子句包含用于联接表或将谓词应用于表中的列的条件。可在 WHERE 子句或 FROM 子句中使用适当的语法对表进行内部联接。外部联接条件必须在 FROM 子句中指定。

## 语法
<a name="r_WHERE_clause-synopsis"></a>

```
[ WHERE condition ]
```

## *condition*
<a name="r_WHERE_clause-synopsis-condition"></a>

任何具有布尔型结果的搜索条件，例如，联接条件或表列上的谓词。以下示例是有效的联接条件：

```
sales.listid=listing.listid
sales.listid<>listing.listid
```

以下示例是表中的列上的有效条件：

```
catgroup like 'S%'
venueseats between 20000 and 50000
eventname in('Jersey Boys','Spamalot')
year=2008
length(catdesc)>25
date_part(month, caldate)=6
```

条件可以是简单条件或复杂条件；对于复杂条件，可以使用圆括号来分隔逻辑单元。在下面的示例中，用圆括号将联接条件括起来。

```
where (category.catid=event.catid) and category.catid in(6,7,8)
```

## 使用说明
<a name="r_WHERE_clause_usage_notes"></a>

您可在 WHERE 子句中使用别名来引用选择列表表达式。

不能限制 WHERE 子句中的聚合函数的结果；要实现此目的，请使用 HAVING 子句。

WHERE 子句中受限制的列必须派生自 FROM 子句中的表引用。

## 示例
<a name="r_SELECT_synopsis-example"></a>

以下查询使用不同的 WHERE 子句限制的组合，包括 SALES 表和 EVENT 表的联接条件、EVENTNAME 列上的谓词以及 STARTTIME 列上的两个谓词。

```
select eventname, starttime, pricepaid/qtysold as costperticket, qtysold
from sales, event
where sales.eventid = event.eventid
and eventname='Hannah Montana'
and date_part(quarter, starttime) in(1,2)
and date_part(year, starttime) = 2008
order by 3 desc, 4, 2, 1 limit 10;

eventname    |      starttime      |   costperticket   | qtysold
----------------+---------------------+-------------------+---------
Hannah Montana | 2008-06-07 14:00:00 |     1706.00000000 |       2
Hannah Montana | 2008-05-01 19:00:00 |     1658.00000000 |       2
Hannah Montana | 2008-06-07 14:00:00 |     1479.00000000 |       1
Hannah Montana | 2008-06-07 14:00:00 |     1479.00000000 |       3
Hannah Montana | 2008-06-07 14:00:00 |     1163.00000000 |       1
Hannah Montana | 2008-06-07 14:00:00 |     1163.00000000 |       2
Hannah Montana | 2008-06-07 14:00:00 |     1163.00000000 |       4
Hannah Montana | 2008-05-01 19:00:00 |      497.00000000 |       1
Hannah Montana | 2008-05-01 19:00:00 |      497.00000000 |       2
Hannah Montana | 2008-05-01 19:00:00 |      497.00000000 |       4
(10 rows)
```

# WHERE 子句中的 Oracle 样式的外部联接
<a name="r_WHERE_oracle_outer"></a>

为了与 Oracle 兼容，Amazon Redshift 支持 WHERE 子句联接条件中的 Oracle 外部联接运算符 (\$1)。此运算符仅用于定义外部联接条件；不要尝试在其他上下文中使用它。在大多数情况下，会无提示忽略此运算符的其他使用方式。

外部联接返回与内部联接相同的所有行，还返回一个或两个表中的非匹配行。在 FROM 子句中，可以指定左、右和完全外部联接。在 WHERE 子句中，只能指定左和右外部联接。

要对表 TABLE1 和 TABLE2 执行外部联接并返回 TABLE1 中的非匹配行（左外部联接），请在 FROM 子句中指定 `TABLE1 LEFT OUTER JOIN TABLE2`，或者将 (\$1) 运算符应用于 WHERE 子句中的 TABLE2 中的所有联接列。对于 TABLE1 中的在 TABLE2 中没有匹配行的所有行，在查询结果中，会为包含 TABLE2 中列的任何选择列表表达式显示 Null 值。

要为 TABLE2 中的在 TABLE1 中没有匹配行的所有行生成相同的行为，请在 FROM 子句中指定 `TABLE1 RIGHT OUTER JOIN TABLE2`，或者将 (\$1) 运算符应用于 WHERE 子句中的 TABLE1 中的所有联接列。

## 基本语法
<a name="r_WHERE_oracle_outer-basic-syntax"></a>

```
[ WHERE {
[ table1.column1 = table2.column1(+) ]
[ table1.column1(+) = table2.column1 ]
}
```

第一个条件等效于：

```
from table1 left outer join table2
on table1.column1=table2.column1
```

第二个条件等效于：

```
from table1 right outer join table2
on table1.column1=table2.column1
```

**注意**  
此处显示的语法涵盖了基于一对联接列的 equijoin 的单个示例。不过，其他类型的比较条件和多个联接列对也有效。

例如，以下 WHERE 子句定义基于两个列对的外部联接。(\$1) 运算符必须附加到两个条件中的同一个表：

```
where table1.col1 > table2.col1(+)
and table1.col2 = table2.col2(+)
```

## 使用说明
<a name="r_WHERE_oracle_outer_usage_notes"></a>

如果可能，请在 WHERE 子句中使用标准 FROM 子句 OUTER JOIN 语法而非 (\$1) 运算符。包含 (\$1) 运算符的查询需遵循以下规则：
+ 只能在 WHERE 语句中以及对表或视图中的列的引用中使用 (\$1) 运算符。
+ 不能对表达式应用 (\$1) 运算符。不过，表达式可以包含使用 (\$1) 运算符的列。例如，以下联接条件返回语法错误：

  ```
  event.eventid*10(+)=category.catid
  ```

  不过，以下联接条件有效：

  ```
  event.eventid(+)*10=category.catid
  ```
+ 不能在同时包含 FROM 子句联接语法的查询块中使用 (\$1) 运算符。
+ 如果两个表基于多个联接条件进行联接，则必须在所有这些条件中都使用或都不使用 (\$1) 运算符。使用混合语法样式的联接将作为内部联接执行，不会产生警告。
+ 如果将外部查询中的表与内部查询所生成的表联接，则 (\$1) 运算符不会产生外部联接。
+ 要使用 (\$1) 运算符来将表外部联接到自身，则必须在 FROM 子句中定义表别名并在联接条件中引用这些别名：

  ```
  select count(*)
  from event a, event b
  where a.eventid(+)=b.catid;
  
  count
  -------
  8798
  (1 row)
  ```
+ 不能将包含 (\$1) 运算符的联接条件与 OR 条件或 IN 条件结合使用。例如：

  ```
  select count(*) from sales, listing
  where sales.listid(+)=listing.listid or sales.salesid=0;
  ERROR:  Outer join operator (+) not allowed in operand of OR or IN.
  ```
+  在对两个以上的表执行外部联接的 WHERE 子句中，只能将 (\$1) 运算符应用于指定的表一次。在下面的示例中，不能在两个连续联接中使用 (\$1) 运算符来引用 SALES 表。

  ```
  select count(*) from sales, listing, event
  where sales.listid(+)=listing.listid and sales.dateid(+)=date.dateid;
  ERROR:  A table may be outer joined to at most one other table.
  ```
+  如果 WHERE 子句外部联接条件将 TABLE2 中的一个列与常量比较，则对该列应用 (\$1) 运算符。如果您包括运算符，则会消除 TABLE1 中的外部联接的行（受限制列包含 null 值）。请参阅下面的“示例”部分。

## 示例
<a name="r_WHERE_oracle_outer-examples"></a>

以下联接查询指定 SALES 和 LISTING 表的左外部联接（基于其 LISTID 列）：

```
select count(*)
from sales, listing
where sales.listid = listing.listid(+);

count
--------
172456
(1 row)
```

以下等效查询生成相同的结果，不过使用的是 FROM 子句联接语法：

```
select count(*)
from sales left outer join listing on sales.listid = listing.listid;

count
--------
172456
(1 row)
```

SALES 表不包含 LISTING 表中所有列表的记录，因为并非所有列表都生成销售值。以下查询对 SALES 和 LISTING 执行外部联接，并返回 LISTING 中的行（甚至在 SALES 表未报告给定列表 ID 的销售值也是如此）。PRICE 和 COMM 列（派生自 SALES 表）在结果集中为这些非匹配行包含 null 值。

```
select listing.listid, sum(pricepaid) as price,
sum(commission) as comm
from listing, sales
where sales.listid(+) = listing.listid and listing.listid between 1 and 5
group by 1 order by 1;

listid | price  |  comm
--------+--------+--------
1 | 728.00 | 109.20
2 |        |
3 |        |
4 |  76.00 |  11.40
5 | 525.00 |  78.75
(5 rows)
```

请注意，在使用 WHERE 子句联接运算符时，FROM 子句中表的顺序并不重要。

WHERE 子句中更复杂的外部联接条件的示例是，对两个表列之间的比较以及带常量的比较执行*与* 运算的条件：

```
where category.catid=event.catid(+) and eventid(+)=796;
```

请注意，在两个位置使用 (\$1) 运算符：首先是在表之间的相等比较中，其次是在 EVENTID 列的比较条件中。此语法的结果是，在计算 EVENTID 的限制时保留外部联接的行。如果您从 EVENTID 限制中删除 (\$1) 运算符，则查询会将此限制视为筛选条件而不是视为外部联接条件的一部分。反过来，将从结果集中消除包含 EVENTID 的 null 值的外部联接的行。

下面是演示此行为的完整查询：

```
select catname, catgroup, eventid
from category, event
where category.catid=event.catid(+) and eventid(+)=796;

catname | catgroup | eventid
-----------+----------+---------
Classical | Concerts |
Jazz | Concerts |
MLB | Sports   |
MLS | Sports   |
Musicals | Shows    | 796
NBA | Sports   |
NFL | Sports   |
NHL | Sports   |
Opera | Shows    |
Plays | Shows    |
Pop | Concerts |
(11 rows)
```

使用 FROM 子句语法的等效查询如下：

```
select catname, catgroup, eventid
from category left join event
on category.catid=event.catid and eventid=796;
```

如果从该查询的 WHERE 子句版本中删除第二个 (\$1) 运算符，则它仅返回 1 行（其中包含 `eventid=796` 的行）。

```
select catname, catgroup, eventid
from category, event
where category.catid=event.catid(+) and eventid=796;

catname | catgroup | eventid
-----------+----------+---------
Musicals | Shows    | 796
(1 row)
```

# GROUP BY 子句
<a name="r_GROUP_BY_clause"></a>

GROUP BY 子句标识查询的分组列。它用于将表中在所有列出的列中具有相同值的行组合在一起。列的列出顺序并不重要。结果是将每组具有共同值的行组合到一个组行中，而该组行表示组中的所有行。使用 GROUP BY 可消除输出中的冗余，并计算适用于这些组的聚合。必须在查询使用标准函数（例如，SUM、AVG 和 COUNT）计算聚合时声明分组列。有关更多信息，请参阅 [聚合函数](c_Aggregate_Functions.md)。

## 语法
<a name="r_GROUP_BY_clause-syntax"></a>

```
[ GROUP BY  expression [, ...] | ALL | aggregation_extension  ]
```

其中，*aggregation\$1extension* 为以下之一：

```
GROUPING SETS ( () | aggregation_extension [, ...] ) |
ROLLUP ( expr [, ...] ) |
CUBE ( expr [, ...] )
```

## 参数
<a name="r_GROUP_BY_clause-parameters"></a>

 *expression*  
列或表达式的列表必须匹配查询的选择列表中的非聚合表达式的列表。例如，考虑以下简单查询。  

```
select listid, eventid, sum(pricepaid) as revenue,
count(qtysold) as numtix
from sales
group by listid, eventid
order by 3, 4, 2, 1
limit 5;

listid | eventid | revenue | numtix
-------+---------+---------+--------
89397  |      47 |   20.00 |      1
106590 |      76 |   20.00 |      1
124683 |     393 |   20.00 |      1
103037 |     403 |   20.00 |      1
147685 |     429 |   20.00 |      1
(5 rows)
```
在此查询中，选择列表包含两个聚合表达式。第一个聚合表达式使用 SUM 函数，第二个聚合表达式使用 COUNT 函数。必须将其余两个列（LISTID 和 EVENTID）声明为分组列。  
GROUP BY 子句中的表达式也可以使用序号来引用选择列表。例如，上一个示例的缩略形式如下。  

```
select listid, eventid, sum(pricepaid) as revenue,
count(qtysold) as numtix
from sales
group by 1,2
order by 3, 4, 2, 1
limit 5;

listid | eventid | revenue | numtix
-------+---------+---------+--------
89397  |      47 |   20.00 |      1
106590 |      76 |   20.00 |      1
124683 |     393 |   20.00 |      1
103037 |     403 |   20.00 |      1
147685 |     429 |   20.00 |      1
(5 rows)
```

ALL  
ALL 表示按照在 SELECT 列表中指定的所有列进行分组，但聚合的列除外。例如，考虑以下查询，该查询按 `col1` 和 `col2` 分组，而不必在 GROUP BY 子句中单独指定它们。列 `col3` 是 `SUM` 函数的参数，因此不进行分组。  

```
SELECT col1, col2 sum(col3) FROM testtable GROUP BY ALL
```
如果您在 SELECT 列表中 EXCLUDE 某列，则 GROUP BY ALL 子句不会根据该特定列对结果进行分组。  

```
SELECT * EXCLUDE col3 FROM testtable GROUP BY ALL
```

 * *aggregation\$1extension* *   
您可以使用聚合扩展 GROUPING SETS、ROLLUP 和 CUBE 在单个语句中执行多个 GROUP BY 操作的工作。有关聚合扩展和相关函数的更多信息，请参阅[聚合扩展](r_GROUP_BY_aggregation-extensions.md)。

## 示例
<a name="r_GROUP_BY_clause-examples"></a>

下面的示例使用包含以下各列的 SALES 表：salesid、listid、sellerid、buyerid、eventid、dateid、qtysold、pricepaid、commission 和 saletime。有关 SALES 表的更多信息，请参阅[示例数据库](c_sampledb.md)。

以下示例查询按 `salesid` 和 `listid` 分组，而不必在 GROUP BY 子句中单独指定它们。列 `qtysold` 是 `SUM` 函数的参数，因此不进行分组。

```
SELECT salesid, listid, sum(qtysold) FROM sales GROUP BY ALL;

salesid | listid  | sum
--------+---------+------
33095   | 36572   | 2	
88268   | 100813  | 4	
110917  | 127048  | 1	
...
```

以下示例查询排除 SELECT 列表中的若干列，因此 GROUP BY ALL 仅对 salesid 和 listid 进行分组。

```
SELECT * EXCLUDE sellerid, buyerid, eventid, dateid, qtysold, pricepaid, commission, saletime 
FROM sales GROUP BY ALL;

salesid | listid 
--------+---------
33095   | 36572   	
88268   | 100813 	
110917  | 127048 	
...
```

# 聚合扩展
<a name="r_GROUP_BY_aggregation-extensions"></a>

Amazon Redshift 支持聚合扩展，以便在单个语句中完成多个 GROUP BY 操作。

 聚合扩展的示例使用 `orders` 表，该表包含电子公司的销售数据。您可以使用以下项创建 `orders`。

```
CREATE TABLE ORDERS (
    ID INT,
    PRODUCT CHAR(20),
    CATEGORY CHAR(20),
    PRE_OWNED CHAR(1),
    COST DECIMAL
);

INSERT INTO ORDERS VALUES
    (0, 'laptop',       'computers',    'T', 1000),
    (1, 'smartphone',   'cellphones',   'T', 800),
    (2, 'smartphone',   'cellphones',   'T', 810),
    (3, 'laptop',       'computers',    'F', 1050),
    (4, 'mouse',        'computers',    'F', 50);
```

## *GROUPING SETS*
<a name="r_GROUP_BY_aggregation-extensions-grouping-sets"></a>

 在单个语句中计算一个或多个分组集。分组集是单个 GROUP BY 子句的集合，这是一组 0 列或更多列，您可以通过这些列对查询的结果集进行分组。GROUP BY GROUPING SETS 等效于对一个按不同列分组的结果集运行 UNION ALL 查询。例如，GROUP BY GROUPING SETS((a), (b)) 等效于 GROUP BY a UNION ALL GROUP BY b。

 以下示例返回按产品类别和所售产品类型分组的订单表产品的成本。

```
SELECT category, product, sum(cost) as total
FROM orders
GROUP BY GROUPING SETS(category, product);

       category       |       product        | total
----------------------+----------------------+-------
 computers            |                      |  2100
 cellphones           |                      |  1610
                      | laptop               |  2050
                      | smartphone           |  1610
                      | mouse                |    50

(5 rows)
```

## *ROLLUP*
<a name="r_GROUP_BY_aggregation-extensions-rollup"></a>

 假设在一个层次结构中，前面的列被视为后续列的父列。ROLLUP 按提供的列对数据进行分组，除了分组行之外，还返回额外的小计行，表示所有分组列级别的总计。例如，您可以使用 GROUP BY ROLLUP((a), (b)) 返回先按 a 分组的结果集，然后在假设 b 是 a 的一个子部分的情况下按 b 分组。ROLLUP 还会返回包含整个结果集而不包含分组列的行。

GROUP BY ROLLUP((a), (b)) 等效于 GROUP BY GROUPING SETS((a,b), (a), ())。

以下示例返回先按类别分组，然后按产品分组，且产品是类别细分项的订单表产品的成本。

```
SELECT category, product, sum(cost) as total
FROM orders
GROUP BY ROLLUP(category, product) ORDER BY 1,2;

       category       |       product        | total
----------------------+----------------------+-------
 cellphones           | smartphone           |  1610
 cellphones           |                      |  1610
 computers            | laptop               |  2050
 computers            | mouse                |    50
 computers            |                      |  2100
                      |                      |  3710
(6 rows)
```

## *CUBE*
<a name="r_GROUP_BY_aggregation-extensions-cube"></a>

 按提供的列对数据进行分组，除了分组行之外，还返回额外的小计行，表示所有分组列级别的总计。CUBE 返回与 ROLLUP 相同的行，同时为 ROLLUP 未涵盖的每个分组列组合添加额外的小计行。例如，您可以使用 GROUP BY CUBE ((a), (b)) 返回先按 a 分组的结果集，然后在假设 b 是 a 的一个子部分的情况下按 b 分组，再然后是单独按 b 分组的结果集。CUBE 还会返回包含整个结果集而不包含分组列的行。

GROUP BY CUBE((a), (b)) 等效于 GROUP BY GROUPING SETS((a, b), (a), (b), ())。

以下示例返回先按类别分组，然后按产品分组，且产品是类别细分项的订单表产品的成本。与前面的 ROLLUP 示例不同，该语句返回每个分组列组合的结果。

```
SELECT category, product, sum(cost) as total
FROM orders
GROUP BY CUBE(category, product) ORDER BY 1,2;

       category       |       product        | total
----------------------+----------------------+-------
 cellphones           | smartphone           |  1610
 cellphones           |                      |  1610
 computers            | laptop               |  2050
 computers            | mouse                |    50
 computers            |                      |  2100
                      | laptop               |  2050
                      | mouse                |    50
                      | smartphone           |  1610
                      |                      |  3710
(9 rows)
```

## *GROUPING/GROUPING\$1ID 函数*
<a name="r_GROUP_BY_aggregation-extentions-grouping"></a>

 ROLLUP 和 CUBE 为结果集添加 NULL 值以表示小计行。例如，GROUP BY ROLLUP((a), (b)) 返回 b 分组列中值为 NULL 的一行或多行，以表明它们是 a 分组列中字段的小计。这些 NULL 值仅用于满足返回元组的格式。

 当您使用 ROLLUP 和 CUBE 对本身存储 NULL 值的关系运行 GROUP BY 操作时，这样生成的结果集会包含看起来具有相同分组列的行。返回前面的示例，如果 b 分组列包含存储的 NULL 值，则 GROUP BY ROLLUP((a), (b)) 返回 b 分组列中值为 NULL 且不是小计的行。

 要区分由 ROLLUP 和 CUBE 创建的 NULL 值和在表本身存储的 NULL 值，可以使用 GROUPING 函数或其别名 GROUPING\$1ID。GROUPING 采用单个分组集作为其参数，并且对于结果集中的每一行，返回与该位置的分组列对应的 0 或 1 位值，然后将该值转换为整数。如果该位置的值是由聚合扩展创建的 NULL 值，则 GROUPING 返回 1。对于所有其他值（包括存储的 NULL 值），该示例返回 0。

 例如，GROUPING(category, product) 为给定行返回以下值，具体取决于该行的分组列值。就本示例而言，表中的所有 NULL 值都是由聚合扩展创建的 NULL 值。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_GROUP_BY_aggregation-extensions.html)

GROUPING 函数按照以下格式显示在查询的 SELECT 列表部分。

```
SELECT ... [GROUPING( expr )...] ...
  GROUP BY ... {CUBE | ROLLUP| GROUPING SETS} ( expr ) ...
```

以下示例与前面的 CUBE 示例相同，但为其分组集添加了 GROUPING 函数。

```
SELECT category, product,
       GROUPING(category) as grouping0,
       GROUPING(product) as grouping1,
       GROUPING(category, product) as grouping2,
       sum(cost) as total
FROM orders
GROUP BY CUBE(category, product) ORDER BY 3,1,2;

       category       |       product        | grouping0 | grouping1 | grouping2 | total
----------------------+----------------------+-----------+-----------+-----------+-------
 cellphones           | smartphone           |         0 |         0 |         0 |  1610
 cellphones           |                      |         0 |         1 |         1 |  1610
 computers            | laptop               |         0 |         0 |         0 |  2050
 computers            | mouse                |         0 |         0 |         0 |    50
 computers            |                      |         0 |         1 |         1 |  2100
                      | laptop               |         1 |         0 |         2 |  2050
                      | mouse                |         1 |         0 |         2 |    50
                      | smartphone           |         1 |         0 |         2 |  1610
                      |                      |         1 |         1 |         3 |  3710
(9 rows)
```

## *部分 ROLLUP 和 CUBE*
<a name="r_GROUP_BY_aggregation-extentions-partial"></a>

 您可以只使用小计的一部分来运行 ROLLUP 和 CUBE 操作。

 部分 ROLLUP 和 CUBE 操作的语法如下所示。

```
GROUP BY expr1, { ROLLUP | CUBE }(expr2, [, ...])
```

在这里，GROUP BY 子句仅在 *expr2* 及更高级别创建小计行。

以下示例显示了对订单表执行的部分 ROLLUP 和 CUBE 操作，首先按产品是否为二手产品进行分组，然后对 category 和 product 列运行 ROLLUP 和 CUBE。

```
SELECT pre_owned, category, product,
       GROUPING(category, product, pre_owned) as group_id,
       sum(cost) as total
FROM orders
GROUP BY pre_owned, ROLLUP(category, product) ORDER BY 4,1,2,3;

 pre_owned |       category       |       product        | group_id | total
-----------+----------------------+----------------------+----------+-------
 F         | computers            | laptop               |        0 |  1050
 F         | computers            | mouse                |        0 |    50
 T         | cellphones           | smartphone           |        0 |  1610
 T         | computers            | laptop               |        0 |  1000
 F         | computers            |                      |        2 |  1100
 T         | cellphones           |                      |        2 |  1610
 T         | computers            |                      |        2 |  1000
 F         |                      |                      |        6 |  1100
 T         |                      |                      |        6 |  2610
(9 rows)

SELECT pre_owned, category, product,
       GROUPING(category, product, pre_owned) as group_id,
       sum(cost) as total
FROM orders
GROUP BY pre_owned, CUBE(category, product) ORDER BY 4,1,2,3;

 pre_owned |       category       |       product        | group_id | total
-----------+----------------------+----------------------+----------+-------
 F         | computers            | laptop               |        0 |  1050
 F         | computers            | mouse                |        0 |    50
 T         | cellphones           | smartphone           |        0 |  1610
 T         | computers            | laptop               |        0 |  1000
 F         | computers            |                      |        2 |  1100
 T         | cellphones           |                      |        2 |  1610
 T         | computers            |                      |        2 |  1000
 F         |                      | laptop               |        4 |  1050
 F         |                      | mouse                |        4 |    50
 T         |                      | laptop               |        4 |  1000
 T         |                      | smartphone           |        4 |  1610
 F         |                      |                      |        6 |  1100
 T         |                      |                      |        6 |  2610
(13 rows)
```

由于 ROLLUP 和 CUBE 操作中不包括 pre-owned 列，因此不存在包括所有其他行的总计行。

## *连接分组*
<a name="r_GROUP_BY_aggregation-extentions-concat"></a>

 您可以连接多个 GROUPING SETS/ROLLUP/CUBE 子句来计算不同级别的小计。连接分组返回所提供分组集的笛卡尔乘积。

 连接 GROUPING SETS/ROLLUP/CUBE 子句的语法如下所示。

```
GROUP BY {ROLLUP|CUBE|GROUPING SETS}(expr1[, ...]),
         {ROLLUP|CUBE|GROUPING SETS}(expr1[, ...])[, ...]
```

考虑以下示例，看看小型连接分组如何生成大的最终结果集。

```
SELECT pre_owned, category, product,
       GROUPING(category, product, pre_owned) as group_id,
       sum(cost) as total
FROM orders
GROUP BY CUBE(category, product), GROUPING SETS(pre_owned, ())
ORDER BY 4,1,2,3;

 pre_owned |       category       |       product        | group_id | total
-----------+----------------------+----------------------+----------+-------
 F         | computers            | laptop               |        0 |  1050
 F         | computers            | mouse                |        0 |    50
 T         | cellphones           | smartphone           |        0 |  1610
 T         | computers            | laptop               |        0 |  1000
           | cellphones           | smartphone           |        1 |  1610
           | computers            | laptop               |        1 |  2050
           | computers            | mouse                |        1 |    50
 F         | computers            |                      |        2 |  1100
 T         | cellphones           |                      |        2 |  1610
 T         | computers            |                      |        2 |  1000
           | cellphones           |                      |        3 |  1610
           | computers            |                      |        3 |  2100
 F         |                      | laptop               |        4 |  1050
 F         |                      | mouse                |        4 |    50
 T         |                      | laptop               |        4 |  1000
 T         |                      | smartphone           |        4 |  1610
           |                      | laptop               |        5 |  2050
           |                      | mouse                |        5 |    50
           |                      | smartphone           |        5 |  1610
 F         |                      |                      |        6 |  1100
 T         |                      |                      |        6 |  2610
           |                      |                      |        7 |  3710
(22 rows)
```

## *嵌套分组*
<a name="r_GROUP_BY_aggregation-extentions-nested"></a>

 您可以使用 GROUPING SETS/ROLLUP/CUBE 操作作为 GROUPING SETS *expr* 来形成嵌套分组。展平嵌套 GROUPING SETS 内的子分组。

 嵌套分组的语法如下所示。

```
GROUP BY GROUPING SETS({ROLLUP|CUBE|GROUPING SETS}(expr[, ...])[, ...])
```

考虑以下示例。

```
SELECT category, product, pre_owned,
       GROUPING(category, product, pre_owned) as group_id,
       sum(cost) as total
FROM orders
GROUP BY GROUPING SETS(ROLLUP(category), CUBE(product, pre_owned))
ORDER BY 4,1,2,3;

       category       |       product        | pre_owned | group_id | total
----------------------+----------------------+-----------+----------+-------
 cellphones           |                      |           |        3 |  1610
 computers            |                      |           |        3 |  2100
                      | laptop               | F         |        4 |  1050
                      | laptop               | T         |        4 |  1000
                      | mouse                | F         |        4 |    50
                      | smartphone           | T         |        4 |  1610
                      | laptop               |           |        5 |  2050
                      | mouse                |           |        5 |    50
                      | smartphone           |           |        5 |  1610
                      |                      | F         |        6 |  1100
                      |                      | T         |        6 |  2610
                      |                      |           |        7 |  3710
                      |                      |           |        7 |  3710
(13 rows)
```

请注意，由于 ROLLUP(category) 和 CUBE(product, pre\$1owned) 都包含分组集 ()，因此表示总计的行是重复的。

## *使用说明*：
<a name="r_GROUP_BY_aggregation-extensions-usage-notes"></a>
+ GROUP BY 子句最多支持 64 个分组集。对于 ROLLUP 和 CUBE，或者 GROUPING SETS、ROLLUP 和 CUBE 的某种组合，此限制适用于隐含的分组集数。例如，GROUP BY CUBE((a), (b)) 计为 4 个分组集，而不是 2 个。
+ 使用聚合扩展时，不能使用常量作为分组列。
+ 无法创建包含重复列的分组集。

# HAVING 子句
<a name="r_HAVING_clause"></a>

HAVING 子句将条件应用于查询返回的中间分组结果集。

## 语法
<a name="r_HAVING_clause-synopsis"></a>

```
[ HAVING condition ]
```

例如，您可以限制 SUM 函数的结果：

```
having sum(pricepaid) >10000
```

在应用所有 WHERE 子句条件并完成 GROUP BY 操作后，应用 HAVING 条件。

条件本身采用与任何 WHERE 子句条件相同的形式。

## 使用说明
<a name="r_HAVING_clause_usage_notes"></a>
+ HAVING 子句条件中引用的任何列必须为分组列或引用了聚合函数结果的列。
+ 在 HAVING 子句中，无法指定：
  + 引用选择列表项的序号。仅 GROUP BY 和 ORDER BY 子句接受序号。

## 示例
<a name="r_HAVING_clause-examples"></a>

以下查询按名称计算所有活动的门票总销售额，然后消除总销售额小于 \$1800000 的活动。HAVING 条件应用于选择列表中聚合函数的结果：`sum(pricepaid)`。

```
select eventname, sum(pricepaid)
from sales join event on sales.eventid = event.eventid
group by 1
having sum(pricepaid) > 800000
order by 2 desc, 1;

eventname        |    sum
-----------------+-----------
Mamma Mia!       | 1135454.00
Spring Awakening |  972855.00
The Country Girl |  910563.00
Macbeth          |  862580.00
Jersey Boys      |  811877.00
Legally Blonde   |  804583.00
```

以下查询计算类似的结果集。不过，在本示例中，HAVING 条件将应用于未在选择列表中指定的聚合：`sum(qtysold)`。将从最终结果中消除未售出 2000 张以上的门票的活动。

```
select eventname, sum(pricepaid)
from sales join event on sales.eventid = event.eventid
group by 1
having sum(qtysold) >2000
order by 2 desc, 1;

eventname        |    sum
-----------------+-----------
Mamma Mia!       | 1135454.00
Spring Awakening |  972855.00
The Country Girl |  910563.00
Macbeth          |  862580.00
Jersey Boys      |  811877.00
Legally Blonde   |  804583.00
Chicago          |  790993.00
Spamalot         |  714307.00
```

以下查询按名称计算所有活动的门票总销售额，然后消除总销售额小于 \$1800000 的活动。HAVING 条件应用于选择列表中聚合函数的结果（对 `sum(pricepaid)` 使用别名 `pp`）。

```
select eventname, sum(pricepaid) as pp
from sales join event on sales.eventid = event.eventid
group by 1
having pp > 800000
order by 2 desc, 1;

eventname        |    pp
-----------------+-----------
Mamma Mia!       | 1135454.00
Spring Awakening |  972855.00
The Country Girl |  910563.00
Macbeth          |  862580.00
Jersey Boys      |  811877.00
Legally Blonde   |  804583.00
```

# QUALIFY 子句
<a name="r_QUALIFY_clause"></a>

QUALIFY 子句根据用户指定的搜索条件，筛选先前计算的窗口函数的结果。您可以使用此子句将筛选条件应用于窗口函数的结果，而无需使用子查询。

此子句与 [HAVING 子句](https://docs.aws.amazon.com/redshift/latest/dg/r_HAVING_clause.html)类似，后者应用条件以进一步从 WHERE 子句筛选行。QUALIFY 和 HAVING 的区别在于，QUALIFY 子句的筛选结果可以基于对数据运行窗口函数的结果。在一个查询中可以同时使用 QUALIFY 和 HAVING 子句。

## 语法
<a name="r_QUALIFY-synopsis"></a>

```
QUALIFY condition
```

**注意**  
如果您在 FROM 子句之后直接使用 QUALIFY 子句，则 FROM 关系名称必须在 QUALIFY 子句之前指定了别名。

## 示例
<a name="r_QUALIFY-examples"></a>

本节中的示例使用下面的示例数据。

```
create table store_sales (ss_sold_date date, ss_sold_time time, 
               ss_item text, ss_sales_price float);
insert into store_sales values ('2022-01-01', '09:00:00', 'Product 1', 100.0),
                               ('2022-01-01', '11:00:00', 'Product 2', 500.0),
                               ('2022-01-01', '15:00:00', 'Product 3', 20.0),
                               ('2022-01-01', '17:00:00', 'Product 4', 1000.0),
                               ('2022-01-01', '18:00:00', 'Product 5', 30.0),
                               ('2022-01-02', '10:00:00', 'Product 6', 5000.0),
                               ('2022-01-02', '16:00:00', 'Product 7', 5.0);
```

以下示例演示了如何查找每天 12:00 之后售出的两件最昂贵的商品。

```
SELECT *
FROM store_sales ss
WHERE ss_sold_time > time '12:00:00'
QUALIFY row_number()
OVER (PARTITION BY ss_sold_date ORDER BY ss_sales_price DESC) <= 2
               

 ss_sold_date | ss_sold_time |  ss_item  | ss_sales_price 
--------------+--------------+-----------+----------------
 2022-01-01   | 17:00:00     | Product 4 |           1000
 2022-01-01   | 18:00:00     | Product 5 |             30
 2022-01-02   | 16:00:00     | Product 7 |              5
```

然后，您可以找到每天售出的最后一件商品。

```
SELECT *
FROM store_sales ss
QUALIFY last_value(ss_item)
OVER (PARTITION BY ss_sold_date ORDER BY ss_sold_time ASC
      ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) = ss_item;
               
ss_sold_date | ss_sold_time |  ss_item  | ss_sales_price 
--------------+--------------+-----------+----------------
 2022-01-01   | 18:00:00     | Product 5 |             30
 2022-01-02   | 16:00:00     | Product 7 |              5
```

以下示例返回与前一个查询相同的记录，即每天售出的最后一件商品，但它没有使用 QUALIFY 子句。

```
SELECT * FROM (
  SELECT *,
  last_value(ss_item)
  OVER (PARTITION BY ss_sold_date ORDER BY ss_sold_time ASC
        ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) ss_last_item
  FROM store_sales ss
)
WHERE ss_last_item = ss_item;
               
 ss_sold_date | ss_sold_time |  ss_item  | ss_sales_price | ss_last_item 
--------------+--------------+-----------+----------------+--------------
 2022-01-02   | 16:00:00     | Product 7 |              5 | Product 7
 2022-01-01   | 18:00:00     | Product 5 |             30 | Product 5
```

# UNION、INTERSECT 和 EXCEPT
<a name="r_UNION"></a>

**Topics**
+ [语法](#r_UNION-synopsis)
+ [参数](#r_UNION-parameters)
+ [集合运算符的计算顺序](#r_UNION-order-of-evaluation-for-set-operators)
+ [使用说明](#r_UNION-usage-notes)
+ [示例 UNION 查询](c_example_union_query.md)
+ [示例 UNION ALL 查询](c_example_unionall_query.md)
+ [示例 INTERSECT 查询](c_example_intersect_query.md)
+ [示例 EXCEPT 查询](c_Example_MINUS_query.md)

UNION、INTERSECT 和 EXCEPT *集合运算符* 用于比较和合并两个单独的查询表达式的结果。例如，如果您希望知道网站的哪些用户既是买家又是卖家且其用户名存储在单独的列或表中，则可查找这两类用户的*交集*。如果您希望知道哪些网站用户是买家而不是卖家，则可使用 EXCEPT 运算符查找这两个用户列表的*差集*。如果您希望构建一个所有用户的列表（无论角色如何），则可使用 UNION 运算符。

## 语法
<a name="r_UNION-synopsis"></a>

```
query
{ UNION [ ALL ] | INTERSECT | EXCEPT | MINUS }
query
```

## 参数
<a name="r_UNION-parameters"></a>

 *query*   
一个查询表达式，该表达式（采用其选择列表形式）对应于紧跟 UNION、INTERSECT 或 EXCEPT 运算符的第二个查询表达式。这两个表达式必须包含数量相同并且数据类型兼容的输出列；否则，无法比较和合并两个结果集。集合运算不允许不同类别的数据类型之间的隐式转换；有关更多信息，请参阅 [类型兼容性和转换](c_Supported_data_types.md#r_Type_conversion)。  
您可以构建包含无限数量的查询表达式并任意组合使用 UNION、INTERSECT 和 EXCEPT 运算符来将这些表达式链接起来的查询。例如，假定表 T1、T2 和 T3 包含兼容的列集，则以下查询结构是有效的：  

```
select * from t1
union
select * from t2
except
select * from t3
order by c1;
```

联合   
从两个查询表达式返回行的集合运算，无论行派生自一个查询表达式还是两个查询表达式。

INTERSECT   
返回派生自两个查询表达式的行的集合运算。将丢弃未同时由两个表达式返回的行。

EXCEPT \$1 MINUS   
返回派生自两个查询表达式之一的行的集合运算。要符合结果的要求，行必须存在于第一个结果表而不存在于第二个结果表中。MINUS 和 EXCEPT 完全同义。

ALL   
ALL 关键字保留由 UNION 生成的任何重复行。未使用 ALL 关键字时的默认行为是丢弃这些重复项。不支持 INTERSECT ALL、EXCEPT ALL 和 MINUS ALL。

## 集合运算符的计算顺序
<a name="r_UNION-order-of-evaluation-for-set-operators"></a>

UNION 和 EXCEPT 集合运算符是左关联的。如果未指定圆括号来影响优先顺序，则将以从左到右的顺序来计算这些集合运算符的组合。例如，在以下查询中，首先计算 T1 和 T2 的 UNION，然后对 UNION 结果执行 EXCEPT 操作：

```
select * from t1
union
select * from t2
except
select * from t3
order by c1;
```

在同一个查询中使用运算符组合时，INTERSECT 运算符优先于 UNION 和 EXCEPT 运算符。例如，以下查询将计算 T2 和 T3 的交集，然后计算得到的结果与 T1 的并集：

```
select * from t1
union
select * from t2
intersect
select * from t3
order by c1;
```

通过添加圆括号，可以强制实施不同的计算顺序。在以下示例中，将 T1 和 T2 的并集结果与 T3 执行交集运算，并且查询可能会生成不同的结果。

```
(select * from t1
union
select * from t2)
intersect
(select * from t3)
order by c1;
```

## 使用说明
<a name="r_UNION-usage-notes"></a>
+ 集合运算查询结果中返回的列名是来自第一个查询表达式中的表的列名（或别名）。由于这些列名可能会造成误解（因为列中的值派生自位于集合运算符任一侧的表），您可能需要为结果集提供有意义的别名。
+ 集合运算符之前的查询表达式不应包含 ORDER BY 子句。仅在包含集合运算符的查询结尾处使用 ORDER BY 子句时，该子句才会生成有意义的排序结果。在这种情况下，ORDER BY 子句应用于所有集合运算的最终结果。最外层的查询也可以包含标准 LIMIT 和 OFFSET 子句。
+ 当集合运算符查询返回小数结果时，将提升对应的结果列以返回相同的精度和小数位数。例如，在以下查询中，T1.REVENUE 为 DECIMAL(10,2) 列而 T2.REVENUE 为 DECIMAL(8,4) 列，小数结果将提升为 DECIMAL(12,4)：

  ```
  select t1.revenue union select t2.revenue;
  ```

  小数位数为 `4`，因为这是两个列的最大小数位数。精度为 `12`，因为 T1.REVENUE 要求小数点左侧有 8 位数 (12 - 4 = 8)。此类提升可确保 UNION 两侧的所有值都适合结果。对于 64 位值，最大结果精度为 19，最大结果小数位数为 18。对于 128 位值，最大结果精度为 38，最大结果小数位数为 37。

  如果生成的数据类型超出 Amazon Redshift 精度和小数位数限制，则查询将返回错误。
+ 对于集合运算，如果对于每个相应的列对，两个数据值*相等* 或*都为 NULL*，则两个行将被视为相同。例如，如果表 T1 和 T2 都包含一列和一行，并且两个表中的行都为 NULL，则对这两个表执行的 INTERSECT 运算将返回该行。

# 示例 UNION 查询
<a name="c_example_union_query"></a>

在以下 UNION 查询中，SALES 表中的行将与 LISTING 表中的行合并。从每个表中选择三个兼容的列；在这种情况下，对应的列具有相同的名称和数据类型。

最终结果集按 LISTING 表中的第一列进行排序且最多包含 5 个具有最高 LISTID 值的行。

```
select listid, sellerid, eventid from listing
union select listid, sellerid, eventid from sales
order by listid, sellerid, eventid desc limit 5;

listid | sellerid | eventid
--------+----------+---------
1 |    36861 |    7872
2 |    16002 |    4806
3 |    21461 |    4256
4 |     8117 |    4337
5 |     1616 |    8647
(5 rows)
```

以下示例说明如何将文本值添加到 UNION 查询的输出，以便您查看哪个查询表达式生成了结果集中的每一行。查询将第一个查询表达式中的行标识为“B”（针对买家），并将第二个查询表达式中的行标识为“S”（针对卖家）。

查询标识门票事务费用等于或大于 \$110000 的买家和卖家。UNION 运算符的任一侧的两个查询表达式之间的唯一差异就是 SALES 表的联接列。

```
select listid, lastname, firstname, username,
pricepaid as price, 'S' as buyorsell
from sales, users
where sales.sellerid=users.userid
and pricepaid >=10000
union
select listid, lastname, firstname, username, pricepaid,
'B' as buyorsell
from sales, users
where sales.buyerid=users.userid
and pricepaid >=10000
order by 1, 2, 3, 4, 5;

listid | lastname | firstname | username |   price   | buyorsell
--------+----------+-----------+----------+-----------+-----------
209658 | Lamb     | Colette   | VOR15LYI |  10000.00 | B
209658 | West     | Kato      | ELU81XAA |  10000.00 | S
212395 | Greer    | Harlan    | GXO71KOC |  12624.00 | S
212395 | Perry    | Cora      | YWR73YNZ |  12624.00 | B
215156 | Banks    | Patrick   | ZNQ69CLT |  10000.00 | S
215156 | Hayden   | Malachi   | BBG56AKU |  10000.00 | B
(6 rows)
```

以下示例使用 UNION ALL 运算符，因为需要在结果中保留重复行（如果发现重复行）。对于一系列特定的活动 ID，查询为与每个活动关联的每个销售值返回 0 行或多个行，并为该活动的每个列表返回 0 行或 1 个行。活动 ID 对于 LISTING 和 EVENT 表中的每个行是唯一的，但对于 SALES 表中的活动和列表 ID 的相同组合，可能有多个销售值。

结果集中的第三个列标识行的来源。如果行来自 SALES 表，则在 SALESROW 列中将其标记为“Yes”。（SALESROW 是 SALES.LISTID 的别名。） 如果行来自 LISTING 表，则在 SALESROW 列中将其标记为“No”。

在本示例中，结果集包含针对列表 500，活动 7787 的三个销售行。换而言之，将针对此列表和活动组合执行三个不同的事务。其他两个列表（501 和 502）不生成任何销售值，因此只有查询为这些列表 ID 生成的行来自 LISTING 表 (SALESROW = 'No')。

```
select eventid, listid, 'Yes' as salesrow
from sales
where listid in(500,501,502)
union all
select eventid, listid, 'No'
from listing
where listid in(500,501,502)
order by listid asc;

eventid | listid | salesrow
---------+--------+----------
7787 |    500 | No
7787 |    500 | Yes
7787 |    500 | Yes
7787 |    500 | Yes
6473 |    501 | No
5108 |    502 | No
(6 rows)
```

如果运行不带 ALL 关键字的相同查询，则结果只保留其中一个销售交易。

```
select eventid, listid, 'Yes' as salesrow
from sales
where listid in(500,501,502)
union
select eventid, listid, 'No'
from listing
where listid in(500,501,502)
order by listid asc;

eventid | listid | salesrow
---------+--------+----------
7787 |    500 | No
7787 |    500 | Yes
6473 |    501 | No
5108 |    502 | No
(4 rows)
```

# 示例 UNION ALL 查询
<a name="c_example_unionall_query"></a>

以下示例使用 UNION ALL 运算符，因为需要在结果中保留重复行（如果发现重复行）。对于一系列特定的活动 ID，查询为与每个活动关联的每个销售值返回 0 行或多个行，并为该活动的每个列表返回 0 行或 1 个行。活动 ID 对于 LISTING 和 EVENT 表中的每个行是唯一的，但对于 SALES 表中的活动和列表 ID 的相同组合，可能有多个销售值。

结果集中的第三个列标识行的来源。如果行来自 SALES 表，则在 SALESROW 列中将其标记为“Yes”。（SALESROW 是 SALES.LISTID 的别名。） 如果行来自 LISTING 表，则在 SALESROW 列中将其标记为“No”。

在本示例中，结果集包含针对列表 500，活动 7787 的三个销售行。换而言之，将针对此列表和活动组合执行三个不同的事务。其他两个列表（501 和 502）不生成任何销售值，因此只有查询为这些列表 ID 生成的行来自 LISTING 表 (SALESROW = 'No')。

```
select eventid, listid, 'Yes' as salesrow
from sales
where listid in(500,501,502)
union all
select eventid, listid, 'No'
from listing
where listid in(500,501,502)
order by listid asc;

eventid | listid | salesrow
---------+--------+----------
7787 |    500 | No
7787 |    500 | Yes
7787 |    500 | Yes
7787 |    500 | Yes
6473 |    501 | No
5108 |    502 | No
(6 rows)
```

如果运行不带 ALL 关键字的相同查询，则结果只保留其中一个销售交易。

```
select eventid, listid, 'Yes' as salesrow
from sales
where listid in(500,501,502)
union
select eventid, listid, 'No'
from listing
where listid in(500,501,502)
order by listid asc;

eventid | listid | salesrow
---------+--------+----------
7787 |    500 | No
7787 |    500 | Yes
6473 |    501 | No
5108 |    502 | No
(4 rows)
```

# 示例 INTERSECT 查询
<a name="c_example_intersect_query"></a>

将以下示例与第一个 UNION 示例进行比较。这两个示例之间的唯一差异是所使用的集合运算符，但结果完全不同。仅其中一行相同：

```
235494 |    23875 |    8771
```

 这是在包含 5 行的有限结果中，同时在两个表中找到的唯一行。

```
select listid, sellerid, eventid from listing
intersect
select listid, sellerid, eventid from sales
order by listid desc, sellerid, eventid
limit 5;

listid | sellerid | eventid
--------+----------+---------
235494 |    23875 |    8771
235482 |     1067 |    2667
235479 |     1589 |    7303
235476 |    15550 |     793
235475 |    22306 |    7848
(5 rows)
```

下面的查询查找 3 月份同时在纽约和洛杉矶举办的活动（已销售这些活动的门票）。这两个查询表达式之间的差异是 VENUECITY 列上的约束。

```
select distinct eventname from event, sales, venue
where event.eventid=sales.eventid and event.venueid=venue.venueid
and date_part(month,starttime)=3 and venuecity='Los Angeles'
intersect
select distinct eventname from event, sales, venue
where event.eventid=sales.eventid and event.venueid=venue.venueid
and date_part(month,starttime)=3 and venuecity='New York City'
order by eventname asc;

eventname
----------------------------
A Streetcar Named Desire
Dirty Dancing
Electra
Running with Annalise
Hairspray
Mary Poppins
November
Oliver!
Return To Forever
Rhinoceros
South Pacific
The 39 Steps
The Bacchae
The Caucasian Chalk Circle
The Country Girl
Wicked
Woyzeck
(16 rows)
```

# 示例 EXCEPT 查询
<a name="c_Example_MINUS_query"></a>

TICKIT 数据库中的 CATEGORY 表包含以下 11 行：

```
 catid | catgroup |  catname  |                  catdesc
-------+----------+-----------+--------------------------------------------
   1   | Sports   | MLB       | Major League Baseball
   2   | Sports   | NHL       | National Hockey League
   3   | Sports   | NFL       | National Football League
   4   | Sports   | NBA       | National Basketball Association
   5   | Sports   | MLS       | Major League Soccer
   6   | Shows    | Musicals  | Musical theatre
   7   | Shows    | Plays     | All non-musical theatre
   8   | Shows    | Opera     | All opera and light opera
   9   | Concerts | Pop       | All rock and pop music concerts
  10   | Concerts | Jazz      | All jazz singers and bands
  11   | Concerts | Classical | All symphony, concerto, and choir concerts
(11 rows)
```

假定 CATEGORY\$1STAGE 表（临时表）包含一个额外行：

```
 catid | catgroup |  catname  |                  catdesc
-------+----------+-----------+--------------------------------------------
1 | Sports   | MLB       | Major League Baseball
2 | Sports   | NHL       | National Hockey League
3 | Sports   | NFL       | National Football League
4 | Sports   | NBA       | National Basketball Association
5 | Sports   | MLS       | Major League Soccer
6 | Shows    | Musicals  | Musical theatre
7 | Shows    | Plays     | All non-musical theatre
8 | Shows    | Opera     | All opera and light opera
9 | Concerts | Pop       | All rock and pop music concerts
10 | Concerts | Jazz      | All jazz singers and bands
11 | Concerts | Classical | All symphony, concerto, and choir concerts
12 | Concerts | Comedy    | All stand up comedy performances
(12 rows)
```

返回两个表之间的差异。换而言之，返回 CATEGORY\$1STAGE 表中存在但 CATEGORY 表中不存在的行：

```
select * from category_stage
except
select * from category;

catid | catgroup | catname |             catdesc
-------+----------+---------+----------------------------------
12 | Concerts | Comedy  | All stand up comedy performances
(1 row)
```

以下等效查询使用同义词 MINUS。

```
select * from category_stage
minus
select * from category;

catid | catgroup | catname |             catdesc
-------+----------+---------+----------------------------------
12 | Concerts | Comedy  | All stand up comedy performances
(1 row)
```

如果反转 SELECT 表达式的顺序，则查询不返回任何行。

# ORDER BY 子句
<a name="r_ORDER_BY_clause"></a>

**Topics**
+ [语法](#r_ORDER_BY_clause-synopsis)
+ [参数](#r_ORDER_BY_clause-parameters)
+ [使用说明](#r_ORDER_BY_usage_notes)
+ [使用 ORDER BY 的示例](r_Examples_with_ORDER_BY.md)

ORDER BY 子句对查询的结果集进行排序。

## 语法
<a name="r_ORDER_BY_clause-synopsis"></a>

```
[ ORDER BY expression [ ASC | DESC ] ]
[ NULLS FIRST | NULLS LAST ]
[ LIMIT { count | ALL } ]
[ OFFSET start ]
```

## 参数
<a name="r_ORDER_BY_clause-parameters"></a>

 *expression*   
一个表达式，通常情况下通过指定选择列表中的一个或多个列，来定义查询结果集的排序顺序。根据二进制 UTF-8 排序方式返回结果。您也可以指定：  
+ 未在选择列表中的列
+ 由查询引用的表中存在的一个或多个列构成的表达式
+ 表示选择列表条目的位置（如果不存在选择列表，则为表中列的位置）的序号
+ 定义选择列表条目的别名
当 ORDER BY 子句包含多个表达式时，将根据第一个表达式对结果集进行排序，然后将第二个表达式应用于具有第一个表达式中的匹配值的行，以此类推。

ASC \$1 DESC   
一个定义表达式的排序顺序的选项，如下所示：  
+ ASC：升序（例如，按数值的从低到高的顺序和字符串的从 A 到 Z 的顺序）。如果未指定选项，则默认情况下将按升序对数据进行排序。
+ DESC：降序（按数值的从高到低的顺序和字符串的从 Z 到 A 的顺序）。

NULLS FIRST \$1 NULLS LAST  
一个选项，指定是应将 NULL 值排在最前（位于非 null 值之前）还是排在最后（位于非 null 值之后）。默认情况下，按 ASC 顺序最后对 NULL 值进行排序和排名，按 DESC 顺序首先对 NULL 值进行排序和排名。

LIMIT *number* \$1 ALL   <a name="order-by-clause-limit"></a>
一个选项，用于控制查询返回的排序行的数目。LIMIT 数字必须为正整数；最大值为 `2147483647`。  
LIMIT 0 不返回任何行。可以使用此语法进行测试：检查查询运行（不显示任何行）或返回表中列的列表。如果使用 LIMIT 0 返回列的列表，则 ORDER BY 子句是多余的。默认值为 LIMIT ALL。

OFFSET *start*   <a name="order-by-clause-offset"></a>
一个选项，指定在开始返回行之前跳过 *start* 前的行数。OFFSET 数字必须为正整数；最大值为 `2147483647`。在与 LIMIT 选项结合使用时，将先跳过 OFFSET 行，然后再开始计算返回的 LIMIT 行数。如果不使用 LIMIT 选项，则结果集中的行数会减少跳过的行数。仍必须扫描 OFFSET 子句跳过的行，因此使用较大的 OFFSET 值可能会非常低效。

## 使用说明
<a name="r_ORDER_BY_usage_notes"></a>

 请注意，使用 ORDER BY 子句时预期会发生以下行为：
+ NULL 值被视为“高于”所有其他值。对于默认的升序排序顺序，NULL 值将排在最后。要更改此行为，请使用 NULLS FIRST 选项。
+ 当查询不包含 ORDER BY 子句时，系统将返回具有不可预测的行顺序的结果集。同一查询执行两次可能会返回具有不同顺序的结果集。
+ 可在不使用 ORDER BY 子句的情况下使用 LIMIT 和 OFFSET 选项；不过，要返回一致的行集，请将这两个选项与 ORDER BY 子句结合使用。
+ 在任何并行系统（例如 Amazon Redshift）中，当 ORDER BY 不生成唯一排序时，行的顺序是不确定的。也就是说，如果 ORDER BY 表达式生成重复值，则这些行的返回顺序可能会因系统或 Amazon Redshift 运行而异。
+ Amazon Redshift 不支持 ORDER BY 子句中的字符串文本。

# 使用 ORDER BY 的示例
<a name="r_Examples_with_ORDER_BY"></a>

返回 CATEGORY 表中的所有 11 行，这些行按第二列 CATGROUP 进行排序。对于具有相同 CATGROUP 值的结果，按字符串长度对 CATDESC 列值进行排序。然后，按列 CATID 和 CATNAME 排序。

```
select * from category order by 2, length(catdesc), 1, 3;

catid | catgroup |  catname  |                  catdesc
------+----------+-----------+----------------------------------------
10    | Concerts | Jazz      | All jazz singers and bands
9     | Concerts | Pop       | All rock and pop music concerts
11    | Concerts | Classical | All symphony, concerto, and choir conce
6     | Shows    | Musicals  | Musical theatre
7     | Shows    | Plays     | All non-musical theatre
8     | Shows    | Opera     | All opera and light opera
5     | Sports   | MLS       | Major League Soccer
1     | Sports   | MLB       | Major League Baseball
2     | Sports   | NHL       | National Hockey League
3     | Sports   | NFL       | National Football League
4     | Sports   | NBA       | National Basketball Association
(11 rows)
```

返回 SALES 表中的选定列（按最高的 QTYSOLD 值排序）。将结果限制为前 10 行：

```
select salesid, qtysold, pricepaid, commission, saletime from sales
order by qtysold, pricepaid, commission, salesid, saletime desc
limit 10;

salesid | qtysold | pricepaid | commission |      saletime
--------+---------+-----------+------------+---------------------
15401   |       8 |    272.00 |      40.80 | 2008-03-18 06:54:56
61683   |       8 |    296.00 |      44.40 | 2008-11-26 04:00:23
90528   |       8 |    328.00 |      49.20 | 2008-06-11 02:38:09
74549   |       8 |    336.00 |      50.40 | 2008-01-19 12:01:21
130232  |       8 |    352.00 |      52.80 | 2008-05-02 05:52:31
55243   |       8 |    384.00 |      57.60 | 2008-07-12 02:19:53
16004   |       8 |    440.00 |      66.00 | 2008-11-04 07:22:31
489     |       8 |    496.00 |      74.40 | 2008-08-03 05:48:55
4197    |       8 |    512.00 |      76.80 | 2008-03-23 11:35:33
16929   |       8 |    568.00 |      85.20 | 2008-12-19 02:59:33
(10 rows)
```

通过使用 LIMIT 0 语法返回列的列表，但不返回行：

```
select * from venue limit 0;
venueid | venuename | venuecity | venuestate | venueseats
---------+-----------+-----------+------------+------------
(0 rows)
```

# CONNECT BY 子句
<a name="r_CONNECT_BY_clause"></a>

CONNECT BY 子句指定层次结构中行之间的关系。您可以使用 CONNECT BY 按层次结构顺序选择行，方法是将表联接到表本身并处理分层数据。例如，您可以使用它以递归方式循环浏览组织结构图和列出数据。

分层查询按以下顺序处理：

1. 如果 FROM 子句有联接，则首先对其进行处理。

1. 对 CONNECT BY 子句求值。

1. 对 WHERE 子句求值。

## 语法
<a name="r_CONNECT_BY_clause-synopsis"></a>

```
[START WITH start_with_conditions]
CONNECT BY connect_by_conditions
```

**注意**  
虽然 START 和 CONNECT 不是保留字，但如果您在查询中使用 START 和 CONNECT 作为表别名，请使用分隔标识符（双引号）或 AS，以避免在运行时失败。

```
SELECT COUNT(*)
FROM Employee "start"
CONNECT BY PRIOR id = manager_id
START WITH name = 'John'
```

```
SELECT COUNT(*)
FROM Employee AS start
CONNECT BY PRIOR id = manager_id
START WITH name = 'John'
```

## 参数
<a name="r_CONNECT_BY_parameters"></a>

 *start\$1with\$1conditions*   
指定层次结构根行的条件

 *connect\$1by\$1conditions*   
指定层次结构的父行和子行之间关系的条件。必须使用用于引用父行的 ` ` 一元运算符限定至少一个条件。  

```
PRIOR column = expression
-- or
expression > PRIOR column
```

## 运算符
<a name="r_CONNECT_BY_operators"></a>

您可以在 CONNECT BY 查询中使用以下运算符。

 *LEVEL*   
返回层次结构中当前行级别的伪列。为根行返回 1，为根行的子行返回 2，依此类推。

 *PRIOR*   
一元运算符，用于计算层次结构中当前行的父行的表达式。

## 示例
<a name="r_CONNECT_BY_example"></a>

以下示例是 CONNECT BY 查询，该示例返回直接或间接向 John 报告的员工数量，不超过 4 个级别。

```
SELECT id, name, manager_id
FROM employee
WHERE LEVEL < 4
START WITH name = 'John'
CONNECT BY PRIOR id = manager_id;
```

以下是查询的结果。

```
id      name      manager_id
------+----------+--------------
  101     John        100
  102     Jorge       101
  103     Kwaku       101
  110     Liu         101
  201     Sofía       102
  106     Mateo       102
  110     Nikki       103
  104     Paulo       103
  105     Richard     103
  120     Saanvi      104
  200     Shirley     104
  205     Zhang       104
```

 此示例的表定义：

```
CREATE TABLE employee (
   id INT,
   name VARCHAR(20),
   manager_id INT
   );
```

 以下是插入到表中的行。

```
INSERT INTO employee(id, name, manager_id)  VALUES
(100, 'Carlos', null),
(101, 'John', 100),
(102, 'Jorge', 101),
(103, 'Kwaku', 101),
(110, 'Liu', 101),
(106, 'Mateo', 102),
(110, 'Nikki', 103),
(104, 'Paulo', 103),
(105, 'Richard', 103),
(120, 'Saanvi', 104),
(200, 'Shirley', 104),
(201, 'Sofía', 102),
(205, 'Zhang', 104);
```

以下是 John 所在部门的组织结构图。

![\[John 所在部门的组织结构图。\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/images/org-chart.png)


# 子查询示例
<a name="r_Subquery_examples"></a>

以下示例说明子查询适合 SELECT 查询的不同方式。有关使用子查询的另一个示例，请参阅[JOIN 示例](r_Join_examples.md)。

## SELECT 列表子查询
<a name="r_Subquery_examples-select-list-subquery"></a>

以下示例在 SELECT 列表中包含一个子查询。此子查询是*标量*：它只返回一列和一个值，该值将在从外部查询返回的每个行的结果中重复。此查询将子查询计算出的 Q1SALES 值与外部查询定义的 2008 年其他两个季度（第 2 季度和第 3 季度）的销售值进行比较。

```
select qtr, sum(pricepaid) as qtrsales,
(select sum(pricepaid)
from sales join date on sales.dateid=date.dateid
where qtr='1' and year=2008) as q1sales
from sales join date on sales.dateid=date.dateid
where qtr in('2','3') and year=2008
group by qtr
order by qtr;

qtr  |  qtrsales   |   q1sales
-------+-------------+-------------
2     | 30560050.00 | 24742065.00
3     | 31170237.00 | 24742065.00
(2 rows)
```

## WHERE 子句子查询
<a name="r_Subquery_examples-where-clause-subquery"></a>

以下示例在 WHERE 子句中包含一个表子查询。此子查询生成多个行。在本示例中，行只包含一列，但表子查询可以包含多个列和行，就像任何其他表一样。

此查询查找门票销量排名前 10 位的卖家。前 10 位卖家的列表受子查询的限制，这将删除居住在设有售票点的城市的用户。可以使用不同的方式编写此查询；例如，可将子查询重新编写为主查询中的联接。

```
select firstname, lastname, city, max(qtysold) as maxsold
from users join sales on users.userid=sales.sellerid
where users.city not in(select venuecity from venue)
group by firstname, lastname, city
order by maxsold desc, city desc
limit 10;

firstname | lastname  |      city      | maxsold
-----------+-----------+----------------+---------
Noah       | Guerrero | Worcester      |       8
Isadora    | Moss     | Winooski       |       8
Kieran     | Harrison | Westminster    |       8
Heidi      | Davis    | Warwick        |       8
Sara       | Anthony  | Waco           |       8
Bree       | Buck     | Valdez         |       8
Evangeline | Sampson  | Trenton        |       8
Kendall    | Keith    | Stillwater     |       8
Bertha     | Bishop   | Stevens Point  |       8
Patricia   | Anderson | South Portland |       8
(10 rows)
```

## WITH 子句子查询
<a name="r_Subquery_examples-with-clause-subqueries"></a>

请参阅 [WITH 子句](r_WITH_clause.md)。

# 关联的子查询
<a name="r_correlated_subqueries"></a>

以下示例将*关联子查询* 包含在 WHERE 子句中；此类型的子查询包含其列与由外部查询生成的列之间的一个或多个关联。在本示例中，关联为 `where s.listid=l.listid`。对于外部查询生成的每一行，将执行子查询以限定或取消限定行。

```
select salesid, listid, sum(pricepaid) from sales s
where qtysold=
(select max(numtickets) from listing l
where s.listid=l.listid)
group by 1,2
order by 1,2
limit 5;

salesid | listid |   sum
--------+--------+----------
 27     |     28 | 111.00
 81     |    103 | 181.00
 142    |    149 | 240.00
 146    |    152 | 231.00
 194    |    210 | 144.00
(5 rows)
```

## 不支持的关联子查询模式
<a name="r_correlated_subqueries-correlated-subquery-patterns-that-are-not-supported"></a>

查询计划程序使用名为“子查询去相关性”的查询重写方法来优化多个关联子查询模式以便在 MPP 环境中执行。有多种类型的关联子查询采用 Amazon Redshift 无法去相关性且不支持的模式。包含以下关联引用的查询会返回错误：
+  跳过查询块的关联引用，也称为“跨级关联引用”。例如，在以下查询中，包含关联引用的块与跳过的块由 NOT EXISTS 谓词连接：

  ```
  select event.eventname from event
  where not exists
  (select * from listing
  where not exists
  (select * from sales where event.eventid=sales.eventid));
  ```

  在本示例中，跳过的块是针对 LISTING 表执行的子查询。关联引用将 EVENT 表和 SALES 表关联起来。
+  来自作为外部查询中 ON 子句的一部分的子查询的关联引用：

  ```
  select * from category
  left join event
  on category.catid=event.catid and eventid =
  (select max(eventid) from sales where sales.eventid=event.eventid);
  ```

  ON 子句包含从子查询中的 SALES 到外部查询中的 EVENT 的关联引用。
+ 针对 Amazon Redshift 系统表的 Null 敏感型关联引用。例如：

  ```
  select attrelid
  from stv_locks sl, pg_attribute
  where sl.table_id=pg_attribute.attrelid and 1 not in
  (select 1 from pg_opclass where sl.lock_owner = opcowner);
  ```
+ 来自包含窗口函数的子查询内部的关联引用。

  ```
  select listid, qtysold
  from sales s
  where qtysold not in
  (select sum(numtickets) over() from listing l where s.listid=l.listid);
  ```
+ GROUP BY 列中对关联查询结果的引用。例如：

  ```
  select listing.listid,
  (select count (sales.listid) from sales where sales.listid=listing.listid) as list
  from listing
  group by list, listing.listid;
  ```
+ 来自带聚合函数和 GROUP BY 子句（通过 IN 谓词连接到外部查询）的关联引用。（此限制不适用于 MIN 和 MAX 聚合函数。） 例如：

  ```
  select * from listing where listid in
  (select sum(qtysold)
  from sales
  where numtickets>4
  group by salesid);
  ```

# SELECT INTO
<a name="r_SELECT_INTO"></a>

选择任何查询所定义的行，并将这些行插入到新表中。您可以指定是创建临时表还是永久表。

## 语法
<a name="r_SELECT_INTO-synopsis"></a>

```
[ WITH with_subquery [, ...] ]
SELECT
[ TOP number | [ ALL | DISTINCT ]
* | expression [ AS output_name ] [, ...] ]
[ EXCLUDE column_list ]
INTO [ TEMPORARY | TEMP ] [ TABLE ] new_table
[ FROM table_reference [, ...] ]
[ WHERE condition ]
[ [ START WITH expression ] CONNECT BY expression ]
[ GROUP BY ALL | expression [, ...] ]
[ HAVING condition ]
[ QUALIFY condition ]
[ { UNION | ALL | INTERSECT | EXCEPT | MINUS } query ]
[ ORDER BY expression [ ASC | DESC ] ]
[ LIMIT { number | ALL } ]
[ OFFSET start ]
```

 有关此命令的参数的详细信息，请参阅[SELECT](r_SELECT_synopsis.md)。

## 示例
<a name="r_SELECT_INTO-examples"></a>

选择 EVENT 表中的所有行并创建 NEWEVENT 表：

```
select * into newevent from event;
```

选择聚合查询的结果并将这些结果插入到名为 PROFITS 的临时表中：

```
select username, lastname, sum(pricepaid-commission) as profit
into temp table profits
from sales, users
where sales.sellerid=users.userid
group by 1, 2
order by 3 desc;
```

# SET
<a name="r_SET"></a>

设置服务器配置参数的值。使用 SET 命令仅覆盖当前会话或事务持续时间的设置。

使用 [RESET](r_RESET.md) 命令将参数还原为其默认值。

您可以通过多种方式更改服务器配置参数。有关更多信息，请参阅 [修改服务器配置](cm_chap_ConfigurationRef.md#t_Modifying_the_default_settings)。

## 语法
<a name="r_SET-synopsis"></a>

```
SET { [ SESSION | LOCAL ]
{ SEED | parameter_name } { TO | = }
{ value | 'value' | DEFAULT } |
SEED TO value }
```

以下语句将设置会话上下文变量的值。

```
SET { [ SESSION | LOCAL ]
variable_name { TO | = }
{ value | 'value'  }
```

## 参数
<a name="r_SET-parameters"></a>

SESSION   
指定设置对当前会话有效。默认值。

*variable\$1name*   
指定为会话设置的上下文变量的名称。  
命名约定是一个用点分隔的、包含两个部分的名称，例如 *identifier.identifier*。只允许使用一个点分隔符。使用遵循 Amazon Redshift 的标准标识符规则的*标识符*。有关更多信息，请参阅[名称和标识符](r_names.md)。不允许使用分隔标识符。

LOCAL   
指定设置对当前事务有效。

SEED TO *value*   
设置由 RANDOM 函数用于生成随机数的内部种子。  
SET SEED 采用介于 0 和 1 之间的数*值*，并将此数乘以 (231-1) 以用于 [RANDOM 函数](r_RANDOM.md) 函数。如果在多次调用 RANDOM 之前使用 SET SEED，则 RANDOM 会按可预测的顺序生成数字。

 *parameter\$1name*   
要设置的参数的名称。有关参数的信息，请参阅[修改服务器配置](cm_chap_ConfigurationRef.md#t_Modifying_the_default_settings)。

 *值*   
新的参数值。使用单引号将值设置为特定字符串。如果使用 SET SEED，则此参数包含 SEED 值。

DEFAULT   
将参数设置为默认值。

## 示例
<a name="r_SET-examples"></a>

 **更改当前会话的参数** 

以下示例设置日期样式：

```
set datestyle to 'SQL,DMY';
```

 **设置工作负载管理的查询组** 

如果查询组在队列定义中作为集群的 WLM 配置的一部分列出，则可将 QUERY\$1GROUP 参数设置为列出的查询组名称。后续查询将分配给关联的查询队列。QUERY\$1GROUP 设置在会话的持续时间内或遇到 RESET QUERY\$1GROUP 命令之前保持有效。

此示例将两个查询作为查询组“priority”的一部分运行，然后重置查询组。

```
set query_group to 'priority';
select tbl, count(*)from stv_blocklist;
select query, elapsed, substring from svl_qlog order by query desc limit 5;
reset query_group;
```

有关更多信息，请参阅 [工作负载管理](cm-c-implementing-workload-management.md)。

 **更改会话的默认身份命名空间** 

数据库用户可以设置 `default_identity_namespace`。此示例说明如何使用 `SET SESSION` 来覆盖当前会话持续时间的设置，然后显示新的身份提供者值。当您将身份提供者与 Redshift 和 IAM Identity Center 结合使用时，最常使用此方法。有关将身份提供者与 Redshift 结合使用的更多信息，请参阅[将 Redshift 与 IAM Identity Center 连接，为用户提供单点登录体验](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-idp-connect.html)。

```
SET SESSION default_identity_namespace = 'MYCO';
         
SHOW default_identity_namespace;
```

运行命令后，您可以运行 GRANT 语句或 CREATE 语句，如下所示：

```
GRANT SELECT ON TABLE mytable TO alice;

GRANT UPDATE ON TABLE mytable TO salesrole;
         
CREATE USER bob password 'md50c983d1a624280812631c5389e60d48c';
```

在这种情况下，设置默认身份命名空间的效果等同于为每个身份添加命名空间前缀。在本例中，`alice` 替换为 `MYCO:alice`。有关与 IAM Identity Center 的 Redshift 配置相关的设置的更多信息，请参阅 [ALTER SYSTEM](r_ALTER_SYSTEM.md) 和 [ALTER IDENTITY PROVIDER](r_ALTER_IDENTITY_PROVIDER.md)。

 **设置查询组的标签** 

QUERY\$1GROUP 参数为在同一个会话中 SET 命令之后执行的一个或多个查询定义标签。反过来，在执行查询并可将其用于约束从 STL\$1QUERY 和 STV\$1INFLIGHT 系统表以及 SVL\$1QLOG 视图返回的结果时，将记录此标签。

```
show query_group;
query_group
-------------
unset
(1 row)

set query_group to '6 p.m.';


show query_group;
query_group
-------------
6 p.m.
(1 row)

select * from sales where salesid=500;
salesid | listid | sellerid | buyerid | eventid | dateid | ...
---------+--------+----------+---------+---------+--------+-----
500 |    504 |     3858 |    2123 |    5871 |   2052 | ...
(1 row)

reset query_group;

select query, trim(label) querygroup, pid, trim(querytxt) sql
from stl_query
where label ='6 p.m.';
query | querygroup |  pid  |                  sql
-------+------------+-------+----------------------------------------
57 | 6 p.m.     | 30711 | select * from sales where salesid=500;
(1 row)
```

查询组标签是一个非常有用的机制，可用于隔离作为脚本一部分运行的单个查询或查询组。您不需要通过查询 ID 来标识和跟踪查询；而可以通过查询的标签来跟踪查询。

 **设置用于生成随机数的种子值** 

以下示例将 SEED 选项与 SET 结合使用，使 RANDOM 函数按可预测的顺序生成数字。

首先，返回三个 RANDOM 整数，而不先设置 SEED 值：

```
select cast (random() * 100 as int);
int4
------
6
(1 row)

select cast (random() * 100 as int);
int4
------
68
(1 row)

select cast (random() * 100 as int);
int4
------
56
(1 row)
```

现在，将 SEED 值设置为 `.25`，并返回 3 个以上的 RANDOM 数字：

```
set seed to .25;

select cast (random() * 100 as int);
int4
------
21
(1 row)

select cast (random() * 100 as int);
int4
------
79
(1 row)

select cast (random() * 100 as int);
int4
------
12
(1 row)
```

最后，将 SEED 值重置为 `.25`，并验证 RANDOM 是否返回与前三个调用相同的结果：

```
set seed to .25;

select cast (random() * 100 as int);
int4
------
21
(1 row)

select cast (random() * 100 as int);
int4
------
79
(1 row)

select cast (random() * 100 as int);
int4
------
12
(1 row)
```

以下示例设置自定义上下文变量。

```
SET app_context.user_id TO 123;
SET app_context.user_id TO 'sample_variable_value';
```

# SET SESSION AUTHORIZATION
<a name="r_SET_SESSION_AUTHORIZATION"></a>

设置当前会话的用户名。

您可以使用 SET SESSION AUTHORIZATION 命令以非特权用户身份临时运行会话或事务，来测试数据库访问。您必须是数据库超级用户才能执行此命令。

## 语法
<a name="r_SET_SESSION_AUTHORIZATION-synopsis"></a>

```
SET [ LOCAL ] SESSION AUTHORIZATION { user_name | DEFAULT }
```

## 参数
<a name="r_SET_SESSION_AUTHORIZATION-parameters"></a>

LOCAL  
指定设置对当前事务有效。忽略此参数将指定设置对当前会话有效。

 *user\$1name*   
要设置的用户的名称。可以使用标识符或字符串文本的形式来编写用户名。

DEFAULT  
将会话用户名设置为默认值。

## 示例
<a name="r_SET_SESSION_AUTHORIZATION-examples"></a>

以下示例将当前会话的用户名设置为 `dwuser`:

```
SET SESSION AUTHORIZATION 'dwuser';
```

以下示例将当前事务的用户名设置为 `dwuser`:

```
SET LOCAL SESSION AUTHORIZATION 'dwuser';
```

此示例将当前会话的用户名设置为默认用户名：

```
SET SESSION AUTHORIZATION DEFAULT;
```

# SET SESSION CHARACTERISTICS
<a name="r_SET_SESSION_CHARACTERISTICS"></a>

此命令已被弃用。

# SHOW
<a name="r_SHOW"></a>

显示服务器配置参数的当前值。如果 SET 命令生效，此值可以是特定于当前会话的值。有关配置参数的列表，请参阅[配置参考](cm_chap_ConfigurationRef.md)。

## 语法
<a name="r_SHOW-synopsis"></a>

```
SHOW { parameter_name | ALL }
```

以下语句显示会话上下文变量的当前值。如果变量不存在，Amazon Redshift 会引发错误。

```
SHOW variable_name
```

## 参数
<a name="r_SHOW-parameters"></a>

 *parameter\$1name*   
显示指定参数的当前值。

ALL   
显示所有参数的当前值。

*variable\$1name*   
显示指定变量的当前值。

## 示例
<a name="r_SHOW-examples"></a>

以下示例显示 query\$1group 参数的值：

```
show query_group;

query_group

unset
(1 row)
```

以下示例显示所有参数及其值的列表：

```
show all;
name        |   setting
--------------------+--------------
datestyle          | ISO, MDY
extra_float_digits | 0
query_group        | unset
search_path        | $user,public
statement_timeout  | 0
```

以下示例显示指定变量的当前值。

```
SHOW app_context.user_id;
```

# SHOW COLUMN GRANTS
<a name="r_SHOW_COLUMN_GRANTS"></a>

显示对表中某个列的授权。

## 所需的权限
<a name="r_SHOW_COLUMN_GRANTS-required-permissions"></a>

目标对象的 SHOW GRANTS 将仅显示对当前用户可见的授权。如果当前用户满足下列条件之一，则能查看授权：
+ 是超级用户
+ 是授权用户
+ 是被授予角色的授权所有者
+ 被授予对象授权所针对的角色

## 语法
<a name="r_SHOW_COLUMN_GRANTS-synopsis"></a>

```
SHOW COLUMN GRANTS ON TABLE
{ database_name.schema_name.table_name | schema_name.table_name }
[FOR {username | ROLE role_name | PUBLIC}]
[LIMIT row_limit]
```

## 参数
<a name="r_SHOW_COLUMN_GRANTS-parameters"></a>

database\$1name  
包含目标表的数据库的名称

schema\$1name  
包含目标表的架构的名称

table\$1name  
目标表的名称

username  
仅在输出中包含对 username 的授权

role\$1name  
仅在输出中包含对 role\$1name 的授权

PUBLIC  
仅在输出中包含对 PUBLIC 的授权

row\$1limit  
要返回的最大行数。*row\$1limit* 可以是 0–10000。

## 示例
<a name="r_SHOW_COLUMN_GRANTS-examples"></a>

以下示例显示表 demo\$1db.demo\$1schema.t100 上的列授权：

```
SHOW COLUMN GRANTS ON TABLE demo_db.demo_schema.t100;
 database_name | schema_name | table_name | column_name | object_type | privilege_type | identity_id | identity_name | identity_type | admin_option | privilege_scope | grantor_name 
---------------+-------------+------------+-------------+-------------+----------------+-------------+---------------+---------------+--------------+-----------------+--------------
 demo_db       | demo_schema | t100       | b           | COLUMN      | UPDATE         |         134 | bob           | user          | f            | COLUMN          | dbadmin
 demo_db       | demo_schema | t100       | a           | COLUMN      | SELECT         |         130 | alice         | user          | f            | COLUMN          | dbadmin
 demo_db       | demo_schema | t100       | a           | COLUMN      | UPDATE         |         130 | alice         | user          | f            | COLUMN          | dbadmin
```

以下示例显示用户 bob 的表 demo\$1schema.t100 上的列授权：

```
SHOW COLUMN GRANTS ON TABLE demo_schema.t100 for bob;
 database_name | schema_name | table_name | column_name | object_type | privilege_type | identity_id | identity_name | identity_type | admin_option | privilege_scope | grantor_name 
---------------+-------------+------------+-------------+-------------+----------------+-------------+---------------+---------------+--------------+-----------------+--------------
 demo_db       | demo_schema | t100       | b           | COLUMN      | UPDATE         |         135 | bob           | user          | f            | COLUMN          | dbadmin
```

# SHOW COLUMNS
<a name="r_SHOW_COLUMNS"></a>

显示表中列的列表以及一些列属性。

每个输出行由以逗号分隔的数据库名称、架构名称、表名、列名、序号位置、列默认值、可为空、数据类型、字符最大长度、数字精度、备注、排序键类型、排序键顺序、分布键、编码和排序规则的列表组成。有关这些属性的更多信息，请参阅 [SVV\$1ALL\$1COLUMNS](r_SVV_ALL_COLUMNS.md)。

如果 SHOW COLUMNS 命令生成的列数超过 10000 列，则会返回错误。

## 所需的权限
<a name="r_SHOW_COLUMNS-privileges"></a>

要查看 Amazon Redshift 表中的列，当前用户必须满足以下条件之一：
+ 是超级用户。
+ 是该表的拥有者。
+ 获得对父架构的 USAGE 权限，并获得对表的 SELECT 权限或对列的 SELECT 权限。

## 语法
<a name="r_SHOW_COLUMNS-synopsis"></a>

```
SHOW COLUMNS FROM TABLE database_name.schema_name.table_name [LIKE 'filter_pattern'] [LIMIT row_limit ]
```

## 参数
<a name="r_SHOW_COLUMNS-parameters"></a>

 *database\$1name*   
包含要列出的表的数据库的名称。  
要显示 AWS Glue Data Catalog 中的表，请指定（`awsdatacatalog`）作为数据库名称，并确保系统配置 `data_catalog_auto_mount` 设置为 `true`。有关更多信息，请参阅 [ALTER SYSTEM](r_ALTER_SYSTEM.md)。

 *schema\$1name*   
包含要列出的表的架构的名称。  
要显示 AWS Glue Data Catalog 表，请提供 AWS Glue 数据库名称作为架构名称。

 *table\$1name*   
包含要列出的列的表的名称。

 *filter\$1pattern*   
一个有效的 UTF-8 字符表达式，具有与表名称匹配的模式。LIKE 选项执行区分大小写的匹配，支持以下模式匹配元字符：      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_SHOW_COLUMNS.html)
如果 *filter\$1pattern* 不包含元字符，则模式仅表示字符串本身；在此情况下，LIKE 的行为与等于运算符相同。

 *row\$1limit*   
要返回的最大行数。*row\$1limit* 可以是 0–10000。

## 示例
<a name="r_SHOW_COLUMNS-examples"></a>

以下示例显示了名为 `sample_data_dev` 的 Amazon Redshift 数据库中的列，这些列位于架构 `tickit` 和表 `event` 中。

```
SHOW COLUMNS FROM TABLE demo_schema.compound_sort_table;

  database_name | schema_name |     table_name      | column_name | ordinal_position | column_default | is_nullable |     data_type     | character_maximum_length | numeric_precision | numeric_scale | remarks | sort_key_type | sort_key | dist_key | encoding | collation 
---------------+-------------+---------------------+-------------+------------------+----------------+-------------+-------------------+--------------------------+-------------------+---------------+---------+---------------+----------+----------+----------+-----------
 demo_db       | demo_schema | compound_sort_table | id          |                1 |                | YES         | integer           |                          |                32 |             0 |         | COMPOUND      |        1 |        1 | delta32k | 
 demo_db       | demo_schema | compound_sort_table | name        |                2 |                | YES         | character varying |                       50 |                   |               |         | COMPOUND      |        2 |          | lzo      | default
 demo_db       | demo_schema | compound_sort_table | date_col    |                3 |                | YES         | date              |                          |                   |               |         |               |        0 |          | delta    | 
 demo_db       | demo_schema | compound_sort_table | amount      |                4 |                | YES         | numeric           |                          |                10 |             2 |         |               |        0 |          | mostly16 |
```

以下示例显示了名为 `awsdatacatalog` 的 AWS Glue Data Catalog 数据库中的表，这些表位于架构 `batman` 和表 `nation` 中。输出仅限于 `2` 行。

```
SHOW COLUMNS FROM TABLE second_db.public.t22;

 database_name | schema_name | table_name | column_name | ordinal_position | column_default | is_nullable |          data_type          | character_maximum_length | numeric_precision | numeric_scale | remarks | sort_key_type | sort_key | dist_key | encoding | collation 
---------------+-------------+------------+-------------+------------------+----------------+-------------+-----------------------------+--------------------------+-------------------+---------------+---------+---------------+----------+----------+----------+-----------
 second_db     | public      | t22        | col1        |                1 |                | YES         | integer                     |                          |                32 |             0 |         | INTERLEAVED   |       -1 |          | mostly8  | 
 second_db     | public      | t22        | col2        |                2 |                | YES         | character varying           |                      100 |                   |               |         | INTERLEAVED   |        2 |          | text255  | default
 second_db     | public      | t22        | col3        |                3 |                | YES         | timestamp without time zone |                          |                   |               |         |               |        0 |          | raw      | 
 second_db     | public      | t22        | col4        |                4 |                | YES         | numeric                     |                          |                10 |             2 |         |               |        0 |          | az64     |
```

# SHOW CONSTRAINTS
<a name="r_SHOW_CONSTRAINTS"></a>

显示表中主键和外键约束的列表。

## 所需的权限
<a name="r_SHOW_CONSTRAINTS-required-permissions"></a>

要对表执行 SHOW CONSTRAINTS，当前用户必须满足下列条件之一：
+ 是超级用户
+ 是该表的拥有者
+ 已被授予父架构的 USAGE 权限以及表的 SELECT 权限

## 语法
<a name="r_SHOW_CONSTRAINTS-synopsis"></a>

```
SHOW CONSTRAINTS {PRIMARY KEYS | FOREIGN KEYS [EXPORTED]}
FROM TABLE
{ database_name.schema_name.table_name | schema_name.table_name }
[LIMIT row_limit]
```

## 参数
<a name="r_SHOW_CONSTRAINTS-parameters"></a>

*database\$1name*  
包含目标表的数据库的名称

*schema\$1name*  
包含目标表的架构的名称

*table\$1name*  
目标表的名称

EXPORTED  
如果指定 EXPORTED，则列出其他表中所有引用目标表的外键。

*row\$1limit*  
要返回的最大行数。*row\$1limit* 可以是 0–10000。

## 示例
<a name="r_SHOW_CONSTRAINTS-examples"></a>

以下示例显示表 demo\$1db.demo\$1schema.pk1 中的主键约束：

```
SHOW CONSTRAINTS PRIMARY KEYS FROM TABLE demo_db.demo_schema.pk1;
 database_name | schema_name | table_name | pk_name  | column_name | key_seq 
---------------+-------------+------------+----------+-------------+---------
 demo_db       | demo_schema | pk1        | pk1_pkey | i           |       1
 demo_db       | demo_schema | pk1        | pk1_pkey | j           |       2
 demo_db       | demo_schema | pk1        | pk1_pkey | c           |       3
```

以下示例显示表 demo\$1schema.fk2 中的外键约束：

```
SHOW CONSTRAINTS FOREIGN KEYS FROM TABLE demo_schema.fk2;
 pk_database_name | pk_schema_name | pk_table_name | pk_column_name | fk_database_name | fk_schema_name | fk_table_name | fk_column_name | key_seq |  fk_name   | pk_name  | update_rule | delete_rule | deferrability 
------------------+----------------+---------------+----------------+------------------+----------------+---------------+----------------+---------+------------+----------+-------------+-------------+---------------
 demo_db          | demo_schema    | pk1           | i              | demo_db          | demo_schema    | fk2           | i              |       1 | fk2_i_fkey | pk1_pkey |             |             | 
 demo_db          | demo_schema    | pk1           | j              | demo_db          | demo_schema    | fk2           | j              |       2 | fk2_i_fkey | pk1_pkey |             |             | 
 demo_db          | demo_schema    | pk1           | c              | demo_db          | demo_schema    | fk2           | c              |       3 | fk2_i_fkey | pk1_pkey |             |             |
```

以下示例显示表 demo\$1schema.pk1 中导出的外键约束：

```
SHOW CONSTRAINTS FOREIGN KEYS EXPORTED FROM TABLE demo_schema.pk1;
 pk_database_name | pk_schema_name | pk_table_name | pk_column_name | fk_database_name | fk_schema_name | fk_table_name | fk_column_name | key_seq |     fk_name     | pk_name  | update_rule | delete_rule | deferrability 
------------------+----------------+---------------+----------------+------------------+----------------+---------------+----------------+---------+-----------------+----------+-------------+-------------+---------------
 demo_db          | demo_schema    | pk1           | i              | demo_db          | demo_schema    | fk2           | i              |       1 | fk2_i_fkey      | pk1_pkey |             |             | 
 demo_db          | demo_schema    | pk1           | j              | demo_db          | demo_schema    | fk2           | j              |       2 | fk2_i_fkey      | pk1_pkey |             |             | 
 demo_db          | demo_schema    | pk1           | c              | demo_db          | demo_schema    | fk2           | c              |       3 | fk2_i_fkey      | pk1_pkey |             |             | 
 demo_db          | demo_schema    | pk1           | i              | demo_db          | demo_schema    | other_fk      | i              |       1 | other_fk_i_fkey | pk1_pkey |             |             | 
 demo_db          | demo_schema    | pk1           | j              | demo_db          | demo_schema    | other_fk      | j              |       2 | other_fk_i_fkey | pk1_pkey |             |             | 
 demo_db          | demo_schema    | pk1           | c              | demo_db          | demo_schema    | other_fk      | c              |       3 | other_fk_i_fkey | pk1_pkey |             |             |
```

# SHOW EXTERNAL TABLE
<a name="r_SHOW_EXTERNAL_TABLE"></a>

显示外部表的定义，包括表属性和列属性。您可以使用 SHOW EXTERNAL TABLE 语句的输出来重新创建表。

有关外部表创建的更多信息，请参阅[CREATE EXTERNAL TABLE](r_CREATE_EXTERNAL_TABLE.md)。

## 语法
<a name="r_SHOW_EXTERNAL_TABLE-synopsis"></a>

```
SHOW EXTERNAL TABLE [external_database].external_schema.table_name [ PARTITION ]
```

## 参数
<a name="r_SHOW_EXTERNAL_TABLE-parameters"></a>

 *external\$1database*   
关联的外部数据库的名称。此参数为可选的。

 *external\$1schema*   
关联的外部 schema 的名称。

 *table\$1name*   
要显示的表的名称。

PARTITION   
显示 ALTER TABLE 语句以将分区添加到表定义。

## 示例
<a name="r_SHOW_EXTERNAL_TABLE-examples"></a>

以下示例基于定义如下的外部表：

```
CREATE EXTERNAL TABLE my_schema.alldatatypes_parquet_test_partitioned (
     csmallint smallint,
     cint int,
     cbigint bigint,
     cfloat float4,
     cdouble float8,
     cchar char(10),
     cvarchar varchar(255),
     cdecimal_small decimal(18,9),
     cdecimal_big decimal(30,15),
     ctimestamp TIMESTAMP,
     cboolean boolean,
     cstring varchar(16383)
)
PARTITIONED BY (cdate date, ctime TIMESTAMP)
STORED AS PARQUET
LOCATION 's3://amzn-s3-demo-bucket/alldatatypes_parquet_partitioned';
```

以下是 SHOW EXTERNAL TABLE 命令和表 `my_schema.alldatatypes_parquet_test_partitioned` 的输出示例。

```
SHOW EXTERNAL TABLE my_schema.alldatatypes_parquet_test_partitioned;
```

```
"CREATE EXTERNAL TABLE my_schema.alldatatypes_parquet_test_partitioned (
    csmallint smallint,
    cint int,
    cbigint bigint,
    cfloat float4,
    cdouble float8,
    cchar char(10),
    cvarchar varchar(255),
    cdecimal_small decimal(18,9),
    cdecimal_big decimal(30,15),
    ctimestamp timestamp,
    cboolean boolean,
    cstring varchar(16383)
)
PARTITIONED BY (cdate date, ctime timestamp)
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION 's3://amzn-s3-demo-bucket/alldatatypes_parquet_partitioned';"
```

以下是同一个表的 SHOW EXTERNAL TABLE 命令和输出的示例，但参数中也指定了数据库。

```
SHOW EXTERNAL TABLE my_database.my_schema.alldatatypes_parquet_test_partitioned;
```

```
"CREATE EXTERNAL TABLE my_database.my_schema.alldatatypes_parquet_test_partitioned (
    csmallint smallint,
    cint int,
    cbigint bigint,
    cfloat float4,
    cdouble float8,
    cchar char(10),
    cvarchar varchar(255),
    cdecimal_small decimal(18,9),
    cdecimal_big decimal(30,15),
    ctimestamp timestamp,
    cboolean boolean,
    cstring varchar(16383)
)
PARTITIONED BY (cdate date, ctime timestamp)
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION 's3://amzn-s3-demo-bucket/alldatatypes_parquet_partitioned';"
```

以下是使用 `PARTITION` 参数时的 SHOW EXTERNAL TABLE 命令和输出的示例。输出包含 ALTER TABLE 语句，可用于将分区添加到表定义。

```
SHOW EXTERNAL TABLE my_schema.alldatatypes_parquet_test_partitioned PARTITION;
```

```
"CREATE EXTERNAL TABLE my_schema.alldatatypes_parquet_test_partitioned (
    csmallint smallint,
    cint int,
    cbigint bigint,
    cfloat float4,
    cdouble float8,
    cchar char(10),
    cvarchar varchar(255),
    cdecimal_small decimal(18,9),
    cdecimal_big decimal(30,15),
    ctimestamp timestamp,
    cboolean boolean,
    cstring varchar(16383)
)
PARTITIONED BY (cdate date)
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION 's3://amzn-s3-demo-bucket/alldatatypes_parquet_partitioned';
ALTER TABLE my_schema.alldatatypes_parquet_test_partitioned ADD IF NOT EXISTS PARTITION (cdate='2021-01-01') LOCATION 's3://amzn-s3-demo-bucket/alldatatypes_parquet_partitioned2/cdate=2021-01-01';
ALTER TABLE my_schema.alldatatypes_parquet_test_partitioned ADD IF NOT EXISTS PARTITION (cdate='2021-01-02') LOCATION 's3://amzn-s3-demo-bucket/alldatatypes_parquet_partitioned2/cdate=2021-01-02';"
```

# SHOW DATABASES
<a name="r_SHOW_DATABASES"></a>

显示来自 Data Catalog 或 Amazon Redshift 数据仓库的数据库。SHOW DATABASES 列出了所有可访问的数据库，例如数据仓库中的 AWS Glue Data Catalog 数据库（awsdatacatalog）、数据共享数据库和 Lake Formation 数据库。

## 所需的权限
<a name="r_SHOW_DATABASES-privileges"></a>

用户可以看到所有数据库，但以下数据库除外：
+ 对于从数据共享创建的具有可见权限的数据库，必须向当前用户授予对该数据库的 USAGE 权限。

## 语法
<a name="r_SHOW_DATABASES-syntax"></a>

要显示来自 Amazon Redshift 数据仓库的数据库，请执行以下操作：

```
SHOW DATABASES 
[ LIKE '<expression>' ]
[ LIMIT row_limit ]
```

要显示 Data Catalog 中的数据库，请执行以下操作：

```
SHOW DATABASES FROM DATA CATALOG 
[ ACCOUNT  '<id1>', '<id2>', ... ]
[ LIKE '<expression>' ]
[ IAM_ROLE default | 'SESSION' | 'arn:aws:iam::<account-id>:role/<role-name>' ]
[ LIMIT row_limit ]
```

## 参数
<a name="r_SHOW_DATABASES-parameters"></a>

ACCOUNT '<id1>', '<id2>', ...  
要从中列出数据库的 AWS Glue Data Catalog 账户。省略此参数将指示 Amazon Redshift 应显示拥有该集群的账户中的数据库。

LIKE '<expression>'  
从数据库列表中筛选出那些与您指定的表达式匹配的数据库。此参数支持使用通配符 %（百分号）和 \$1（下划线）的模式。

IAM\$1ROLE default \$1 'SESSION' \$1 'arn:aws:iam::<account-id>:role/<role-name>'  
如果您在运行 SHOW DATABASES 命令时指定与集群关联的 IAM 角色，则 Amazon Redshift 将在您对数据库运行查询时使用该角色的凭证。  
指定 `default` 关键字表示要使用设置为默认并与集群关联的 IAM 角色。  
如果您使用联合身份连接到 Amazon Redshift 集群并访问使用 [CREATE DATABASE](r_CREATE_DATABASE.md) 命令创建的外部数据库中的表，则使用 `'SESSION'`。有关使用联合身份的示例，请参阅[使用联合身份管理 Amazon Redshift 对本地资源和 Amazon Redshift Spectrum 外部表的访问权限](https://docs.aws.amazon.com/redshift/latest/mgmt/authorization-fas-spectrum.html)，其中说明了如何配置联合身份。  
使用 IAM 角色的 Amazon 资源名称（ARN），您的集群使用该角色进行身份验证和授权。IAM 角色至少必须有权在要访问的 Amazon S3 桶上执行 LIST 操作和有权在该桶包含的 Amazon S3 对象上执行 GET 操作。要了解有关从 AWS Glue Data Catalog 中为数据共享创建并使用 IAM\$1ROLE 的数据库的更多信息，请参阅[以使用者身份使用 Lake Formation 托管式数据共享](https://docs.aws.amazon.com/redshift/latest/dg/lake-formation-getting-started-consumer.html)。  
下面显示了单个 ARN 的 IAM\$1ROLE 参数字符串的语法。  

```
IAM_ROLE 'arn:aws:iam::<aws-account-id>:role/<role-name>'
```
您可以将角色串联起来，以便集群可以承担另一个 IAM 角色 (可能属于其他账户)。您最多可串联 10 个角色。有关更多信息，请参阅 [在 Amazon Redshift Spectrum 中链接 IAM 角色](c-spectrum-iam-policies.md#c-spectrum-chaining-roles)。  
 对于此 IAM 角色，请附加类似于以下内容的 IAM 权限策略。    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AccessSecret",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetResourcePolicy",
                "secretsmanager:GetSecretValue",
                "secretsmanager:DescribeSecret",
                "secretsmanager:ListSecretVersionIds"
            ],
            "Resource": "arn:aws:secretsmanager:us-west-2:123456789012:secret:my-rds-secret-VNenFy"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetRandomPassword",
                "secretsmanager:ListSecrets"
            ],
            "Resource": "*"
        }
    ]
}
```
有关创建 IAM 角色以用于联合查询的步骤，请参阅[创建密钥和 IAM 角色以使用联合查询](federated-create-secret-iam-role.md)。  
请不要在链接的角色列表中包含空格。
下面显示了串联三个角色的语法。  

```
IAM_ROLE 'arn:aws:iam::<aws-account-id>:role/<role-1-name>,arn:aws:iam::<aws-account-id>:role/<role-2-name>,arn:aws:iam::<aws-account-id>:role/<role-3-name>'
```

LIMIT *row\$1limit*  
LIMIT 返回的行数的子句。其中 *row\$1limit* 是要返回的最大行数。*row\$1limit* 可以是 0–10000。

## 示例
<a name="r_SHOW_DATABASES-examples"></a>

以下示例显示了来自账户 ID 123456789012 的所有 Data Catalog 数据库。

```
SHOW DATABASES FROM DATA CATALOG ACCOUNT '123456789012'

  catalog_id  | database_name |                        database_arn                    |     type     |                                             target_database                                      | location | parameters
--------------+---------------+--------------------------------------------------------+--------------+--------------------------------------------------------------------------------------------------+----------+------------
 123456789012 |   database1   | arn:aws:glue:us-east-1:123456789012:database/database1 | Data Catalog |                                                                                                  |          |
 123456789012 |   database2   | arn:aws:glue:us-east-1:123456789012:database/database2 | Data Catalog | arn:aws:redshift:us-east-1:123456789012:datashare:035c45ea-61ce-86f0-8b75-19ac6102c3b7/database2 |          |
```

以下示例演示了如何在使用 IAM 角色的凭证时显示账户 ID 123456789012 中的所有数据目录数据库。

```
SHOW DATABASES FROM DATA CATALOG ACCOUNT '123456789012' IAM_ROLE default;
```

```
SHOW DATABASES FROM DATA CATALOG ACCOUNT '123456789012' IAM_ROLE <iam-role-arn>;
```

以下示例显示了所连接的 Amazon Redshift 数据仓库中的所有数据库。

```
SHOW DATABASES

database_name  | database_owner | database_type        | database_acl | parameters | database_isolation_level
---------------+----------------+----------------------+--------------+------------+--------------------
awsdatacatalog | 1              | auto mounted catalog | NULL         | UNKNOWN    | UNKNOWN
dev            | 1              | local                | NULL         | NULL       | Snapshot Isolation
```

# SHOW FUNCTIONS
<a name="r_SHOW_FUNCTIONS"></a>

显示架构中的函数列表以及这些列出对象的相关信息。

每个输出行均包含 database\$1name、schema\$1name、function\$1name、number\$1of\$1arguments、argument\$1list、return\$1type 和 remarks 列。

如果 SHOW FUNCTIONS 命令返回的行数超过 10000，则该命令会引发错误。

## 所需的权限
<a name="r_SHOW_FUNCTIONS-required-permissions"></a>

要查看 Redshift 架构中的函数，当前用户必须满足下列条件之一：
+ 是超级用户
+ 是该函数的所有者
+ 已被授予父架构的 USAGE 权限以及该函数的 EXECUTE 权限

## 语法
<a name="r_SHOW_FUNCTIONS-synopsis"></a>

```
SHOW FUNCTIONS FROM SCHEMA
[database_name.]schema_name
[LIKE 'filter_pattern'] [LIMIT row_limit]
```

## 参数
<a name="r_SHOW_FUNCTIONS-parameters"></a>

*database\$1name*  
包含要列出的函数的数据库的名称。

*schema\$1name*  
包含要列出的函数的架构的名称。

*filter\$1pattern*  
一个有效的 UTF-8 字符表达式，具有与函数名称匹配的模式。LIKE 选项执行区分大小写的匹配，支持以下模式匹配元字符：      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_SHOW_FUNCTIONS.html)
请注意，filter\$1pattern 仅与函数名称匹配。

*row\$1limit*  
要返回的最大行数。*row\$1limit* 可以是 0–10000。

## 示例
<a name="r_SHOW_FUNCTIONS-examples"></a>

以下示例显示架构 demo\$1db.demo\$1schema 中的函数：

```
SHOW FUNCTIONS FROM SCHEMA demo_db.demo_schema;
 database_name | schema_name |    function_name     | number_of_arguments |                                  argument_list                                  |    return_type    | remarks 
---------------+-------------+----------------------+---------------------+---------------------------------------------------------------------------------+-------------------+---------
 demo_db       | demo_schema | f2                   |                   6 | integer, character varying, numeric, date, timestamp without time zone, boolean | character varying | 
 demo_db       | demo_schema | f_calculate_discount |                   2 | numeric, integer                                                                | numeric           | 
 demo_db       | demo_schema | f_days_between       |                   2 | date, date                                                                      | integer           |
```

以下示例显示架构 demo\$1schema 中名称以“discount”结尾的函数：

```
SHOW FUNCTIONS FROM SCHEMA demo_schema like '%discount';
 database_name | schema_name |    function_name     | number_of_arguments |  argument_list   | return_type | remarks 
---------------+-------------+----------------------+---------------------+------------------+-------------+---------
 demo_db       | demo_schema | f_calculate_discount |                   2 | numeric, integer | numeric     |
```

# SHOW GRANTS
<a name="r_SHOW_GRANTS"></a>

显示用户、角色或对象的授权。对象可以是数据库、架构、表、函数或模板。指定对象（例如表或函数）时，您需要用两部分或三部分表示法对其进行限定。例如，`schema_name.table_name` 或 `database_name.schema_name.table_name`。

如果 SHOW GRANTS 命令返回的行数超过 10000，则该命令会引发错误。

## 所需的权限
<a name="r_SHOW_GRANTS-permissions"></a>

要为目标用户或角色运行 SHOW GRANTS，当前用户必须满足下列条件之一：
+ 是超级用户
+ 是目标用户
+ 是目标角色的所有者
+ 已被授予角色

目标对象的 SHOW GRANTS 将仅显示对当前用户可见的授权。如果当前用户满足下列条件之一，则能查看授权：
+ 是超级用户
+ 是目标用户
+ 是被授予角色的授权所有者
+ 被授予对象授权所针对的角色

## 语法
<a name="r_SHOW_GRANTS-syntax"></a>

以下是显示对象授权的语法。请注意，第二种指定函数的方法仅对从数据共享创建的外部架构和数据库有效。

```
SHOW GRANTS ON
{
 DATABASE database_name |
 FUNCTION {database_name.schema_name.function_name | schema_name.function_name } ( [ [ argname ] argtype [, ...] ] ) |
 FUNCTION {database_name.schema_name.function_name | schema_name.function_name } |
 SCHEMA {database_name.schema_name | schema_name} | 
 { TABLE {database_name.schema_name.table_name | schema_name.table_name} | table_name }
 TEMPLATE {database_name.schema_name.template_name | template_name}
}
[FOR {username | ROLE role_name | PUBLIC}]
[LIMIT row_limit]
```

以下是显示对于用户或角色的授权的语法。

```
SHOW GRANTS FOR
{username | ROLE role_name}
[FROM DATABASE database_name]
[LIMIT row_limit]
```

## 参数
<a name="r_SHOW_GRANTS-parameters"></a>

 *database\$1name*   
要显示其授权的数据库的名称。

 *function\$1name*   
要显示其授权的函数的名称。

template\$1name  
要显示其授权的模板的名称。

 *schema\$1name*   
要显示其授权的架构的名称。

 *table\$1name*   
要显示其授权的表的名称。

FOR *username*   
指示显示用户的授权。

FOR ROLE *role\$1name*   
指示显示角色的授权。

FOR PUBLIC  
指示显示 PUBLIC 的授权。

 *row\$1limit*   
要返回的最大行数。*row\$1limit* 可以是 0–10000。

## 示例
<a name="r_SHOW_GRANTS-examples"></a>

以下示例显示对名为 `dev` 的数据库的所有授权。

```
SHOW GRANTS on database demo_db;

  database_name | privilege_type | identity_id | identity_name | identity_type | admin_option | privilege_scope | grantor_name 
---------------+----------------+-------------+---------------+---------------+--------------+-----------------+--------------
 demo_db       | ALTER          |         112 | alice         | user          | f            | TABLES          | dbadmin
 demo_db       | TRUNCATE       |         112 | alice         | user          | f            | TABLES          | dbadmin
 demo_db       | DROP           |         112 | alice         | user          | f            | TABLES          | dbadmin
 demo_db       | INSERT         |         112 | alice         | user          | f            | TABLES          | dbadmin
 demo_db       | TEMP           |           0 | public        | public        | f            | DATABASE        | dbadmin
 demo_db       | SELECT         |         112 | alice         | user          | f            | TABLES          | dbadmin
 demo_db       | UPDATE         |         112 | alice         | user          | f            | TABLES          | dbadmin
 demo_db       | DELETE         |         112 | alice         | user          | f            | TABLES          | dbadmin
 demo_db       | REFERENCES     |         112 | alice         | user          | f            | TABLES          | dbadmin
```

以下命令显示对名为 `demo` 的架构的所有授权。

```
SHOW GRANTS ON SCHEMA demo_schema;

 schema_name | object_name | object_type | privilege_type | identity_id | identity_name | identity_type | admin_option | privilege_scope | database_name | grantor_name 
-------------+-------------+-------------+----------------+-------------+---------------+---------------+--------------+-----------------+---------------+--------------
 demo_schema | demo_schema | SCHEMA      | ALTER          |         112 | alice         | user          | f            | SCHEMA          | db1           | dbadmin
 demo_schema | demo_schema | SCHEMA      | DROP           |         112 | alice         | user          | f            | SCHEMA          | db1           | dbadmin
 demo_schema | demo_schema | SCHEMA      | USAGE          |         112 | alice         | user          | f            | SCHEMA          | db1           | dbadmin
 demo_schema | demo_schema | SCHEMA      | CREATE         |         112 | alice         | user          | f            | SCHEMA          | db1           | dbadmin
```

以下命令显示名为 `alice` 的用户的所有授权。

```
SHOW GRANTS FOR alice;

 database_name | schema_name | object_name | object_type | privilege_type | identity_id | identity_name | identity_type | privilege_scope | grantor_name 
---------------+-------------+-------------+-------------+----------------+-------------+---------------+---------------+-----------------+--------------
 demo_db       |             |             | DATABASE    | INSERT         |         124 | alice         | user          | TABLES          | dbadmin
 demo_db       |             |             | DATABASE    | SELECT         |         124 | alice         | user          | TABLES          | dbadmin
 demo_db       |             |             | DATABASE    | UPDATE         |         124 | alice         | user          | TABLES          | dbadmin
 demo_db       |             |             | DATABASE    | DELETE         |         124 | alice         | user          | TABLES          | dbadmin
 demo_db       |             |             | DATABASE    | REFERENCES     |         124 | alice         | user          | TABLES          | dbadmin
 demo_db       |             |             | DATABASE    | DROP           |         124 | alice         | user          | TABLES          | dbadmin
 demo_db       |             |             | DATABASE    | TRUNCATE       |         124 | alice         | user          | TABLES          | dbadmin
 demo_db       |             |             | DATABASE    | ALTER          |         124 | alice         | user          | TABLES          | dbadmin
 demo_db       | demo_schema |             | SCHEMA      | USAGE          |         124 | alice         | user          | SCHEMA          | dbadmin
 demo_db       | demo_schema |             | SCHEMA      | CREATE         |         124 | alice         | user          | SCHEMA          | dbadmin
 demo_db       | demo_schema |             | SCHEMA      | DROP           |         124 | alice         | user          | SCHEMA          | dbadmin
 demo_db       | demo_schema |             | SCHEMA      | ALTER          |         124 | alice         | user          | SCHEMA          | dbadmin
 demo_db       | demo_schema | t1          | TABLE       | INSERT         |         124 | alice         | user          | TABLE           | dbadmin
 demo_db       | demo_schema | t1          | TABLE       | SELECT         |         124 | alice         | user          | TABLE           | dbadmin
 demo_db       | demo_schema | t1          | TABLE       | UPDATE         |         124 | alice         | user          | TABLE           | dbadmin
 demo_db       | demo_schema | t1          | TABLE       | DELETE         |         124 | alice         | user          | TABLE           | dbadmin
 demo_db       | demo_schema | t1          | TABLE       | RULE           |         124 | alice         | user          | TABLE           | dbadmin
 demo_db       | demo_schema | t1          | TABLE       | REFERENCES     |         124 | alice         | user          | TABLE           | dbadmin
 demo_db       | demo_schema | t1          | TABLE       | TRIGGER        |         124 | alice         | user          | TABLE           | dbadmin
 demo_db       | demo_schema | t1          | TABLE       | DROP           |         124 | alice         | user          | TABLE           | dbadmin
 demo_db       | demo_schema | t1          | TABLE       | TRUNCATE       |         124 | alice         | user          | TABLE           | dbadmin
 demo_db       | demo_schema | t1          | TABLE       | ALTER          |         124 | alice         | user          | TABLE           | dbadmin
```

```
SHOW GRANTS FOR alice FROM DATABASE second_db;
 database_name | schema_name | object_name | object_type | privilege_type | identity_id | identity_name | identity_type | privilege_scope | grantor_name 
---------------+-------------+-------------+-------------+----------------+-------------+---------------+---------------+-----------------+--------------
 second_db     | public      | t22         | TABLE       | SELECT         |         101 | alice         | user          | TABLE           | dbadmin
```

以下命令显示了名为 `alice` 的用户在名为 `t3` 的表上的所有授权。请注意，您可以使用两部分或三部分表示法来指定表名称。

```
SHOW GRANTS ON TABLE demo_db.demo_schema.t3 FOR ALICE;
 schema_name | object_name | object_type | privilege_type | identity_id | identity_name | identity_type | admin_option | privilege_scope | database_name | grantor_name 
-------------+-------------+-------------+----------------+-------------+---------------+---------------+--------------+-----------------+---------------+--------------
 demo_schema | t3          | TABLE       | ALTER          |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | TRUNCATE       |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | DROP           |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | TRIGGER        |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | SELECT         |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | INSERT         |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | UPDATE         |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | DELETE         |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | RULE           |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | REFERENCES     |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin


SHOW GRANTS ON TABLE demo_schema.t3 FOR ALICE;
 schema_name | object_name | object_type | privilege_type | identity_id | identity_name | identity_type | admin_option | privilege_scope | database_name | grantor_name 
-------------+-------------+-------------+----------------+-------------+---------------+---------------+--------------+-----------------+---------------+--------------
 demo_schema | t3          | TABLE       | ALTER          |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | TRUNCATE       |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | DROP           |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | TRIGGER        |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | SELECT         |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | INSERT         |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | UPDATE         |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | DELETE         |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | RULE           |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 demo_schema | t3          | TABLE       | REFERENCES     |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
```

以下示例显示对名为 `t4` 的表的所有授权。请注意指定表名称的不同方式。

```
SHOW GRANTS ON t4;
 schema_name | object_name | object_type | privilege_type | identity_id | identity_name | identity_type | admin_option | privilege_scope | database_name | grantor_name 
-------------+-------------+-------------+----------------+-------------+---------------+---------------+--------------+-----------------+---------------+--------------
 public      | t4          | TABLE       | ALTER          |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | TRUNCATE       |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | DROP           |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | TRIGGER        |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | SELECT         |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | INSERT         |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | UPDATE         |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | DELETE         |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | RULE           |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | REFERENCES     |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 
SHOW GRANTS ON TABLE public.t4;
 schema_name | object_name | object_type | privilege_type | identity_id | identity_name | identity_type | admin_option | privilege_scope | database_name | grantor_name 
-------------+-------------+-------------+----------------+-------------+---------------+---------------+--------------+-----------------+---------------+--------------
 public      | t4          | TABLE       | ALTER          |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | TRUNCATE       |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | DROP           |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | TRIGGER        |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | SELECT         |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | INSERT         |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | UPDATE         |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | DELETE         |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | RULE           |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
 public      | t4          | TABLE       | REFERENCES     |         130 | alice         | user          | f            | TABLE           | demo_db       | dbadmin
```

# SHOW MODEL
<a name="r_SHOW_MODEL"></a>

显示有关机器学习模型的有用信息，包括其状态、用于创建模型的参数以及具有输入参数类型的预测函数。可以使用 SHOW MODEL 中的信息重新创建模型。如果基表已更改，则使用相同的 SQL 语句运行 CREATE MODEL 会导致生成不同的模型。SHOW MODEL 返回的信息对于模型拥有者和具有 EXECUTE 权限的用户而言是不同的。当模型从 Amazon Redshift 中进行训练或模型为 BYOM 模型时，SHOW MODEL 会显示不同的输出。

## 语法
<a name="r_SHOW_MODEL-synopsis"></a>

```
SHOW MODEL ( ALL | model_name )
```

## 参数
<a name="r_SHOW_MODEL-parameters"></a>

ALL   
返回用户可以使用的所有模型及其 schema。

 *model\$1name*   
模型的名称。schema 中的模型名称必须是唯一的。

## 使用说明
<a name="r_SHOW_MODEL_usage_notes"></a>

SHOW MODEL 命令将返回以下内容：
+ 模型名称。
+ 创建模型所在的 schema。
+ 模型的拥有者。
+ 模型创建时间。
+ 模型的状态，如 READY、TRAINING 或 FAILED。
+ 模型失败的原因消息。
+ 如果模型已完成训练，则会出现验证错误。
+ 为非 BYOM 方法派生模型所需的估计成本。只有模型的拥有者可查看此信息。
+ 用户指定的参数及其值的列表，特别是以下内容：
  + 指定的 TARGET 列。
  + 模型类型，AUTO 或 XGBoost。
  + 问题类型，例如 REGRESSION、BINARY\$1CLASSIFICATION、MULTICLASS\$1CLASSIFICATION。此参数特定于 AUTO。
  + Amazon SageMaker AI 训练作业或创建模型的 Amazon SageMaker AI Autopilot 作业的名称。您可以使用此作业名称在 Amazon SageMaker AI 上查找有关该模型的更多信息。
  + 目标，如 MSE、F1、精度。此参数特定于 AUTO。
  + 所创建的函数的名称。
  + 推理的类型，本地或远程。
  + 预测函数输入参数。
  + 非自带模型 (BYOM) 的预测函数输入参数类型。
  + 预测函数的返回类型。此参数特定于 BYOM。
  + 具有远程推理功能的 BYOM 模型的 Amazon SageMaker AI 端点的名称。
  + IAM 角色。只有模型的拥有者可以看到此内容。
  + 所用的 S3 桶。只有模型的拥有者可以看到此内容。
  + AWS KMS 键（如果提供了一个）。只有模型的拥有者可以看到此内容。
  + 模型可以运行的最长时间。
+ 如果模型类型不是 AUTO，则 Amazon Redshift 还会显示提供的超参数列表及其值。

您还可以在其他目录表（如 pg\$1proc）中查看 SHOW MODEL 提供的一些信息。Amazon Redshift 返回有关在 pg\$1proc 目录表中注册的预测函数的信息。此信息包括预测函数的输入参数名称及其类型。Amazon Redshift 会在 SHOW MODEL 命令中返回相同的信息。

```
SELECT * FROM pg_proc WHERE proname ILIKE '%<function_name>%';
```

## 示例
<a name="r_SHOW_MODEL-examples"></a>

以下示例显示了显示模型输出。

```
SHOW MODEL ALL;

Schema Name |  Model Name
------------+---------------
 public     | customer_churn
```

customer\$1churn 的拥有者可查看以下输出。仅具有 EXECUTE 权限的用户无法看到 IAM 角色、Amazon S3 桶和模式的估计成本。

```
SHOW MODEL customer_churn;

       Key                 |           Value
---------------------------+-----------------------------------
 Model Name                | customer_churn
 Schema Name               | public
 Owner                     | 'owner'
 Creation Time             | Sat, 15.01.2000 14:45:20
 Model State               | READY
 validation:F1             | 0.855
 Estimated Cost            | 5.7
                           |
 TRAINING DATA:            |
 Table                     | customer_data
 Target Column             | CHURN
                           |
 PARAMETERS:               |
 Model Type                | auto
 Problem Type              | binary_classification
 Objective                 | f1
 Function Name             | predict_churn
 Function Parameters       | age zip average_daily_spend average_daily_cases
 Function Parameter Types  | int int float float
 IAM Role                  | 'iam_role'
 KMS Key                   | 'kms_key'
 Max Runtime               | 36000
```

# SHOW DATASHARES
<a name="r_SHOW_DATASHARES"></a>

显示集群中来自同一账户或各账户间的入站和出站共享。如果您未指定数据共享名称，则 Amazon Redshift 会显示集群中所有数据库中的所有数据共享。具有 ALTER 和 SHARE 权限的用户可以看到他们对其拥有权限的共享。

## 语法
<a name="r_SHOW_DATASHARES-synopsis"></a>

```
SHOW DATASHARES [ LIKE 'namepattern' ] 
```

## 参数
<a name="r_SHOW_DATASHARES-parameters"></a>

LIKE  
一个可选子句，用于将指定的名称模式与数据共享的描述进行比较。使用此子句时，Amazon Redshift 仅显示名称与指定名称模式匹配的数据共享。

*namepattern*  
请求的数据共享的名称或要使用通配符匹配的名称的一部分。

## 示例
<a name="r_SHOW_DATASHARES-examples"></a>

以下示例显示集群中的入站和出站共享。

```
SHOW DATASHARES;
SHOW DATASHARES LIKE 'sales%';

share_name   | share_owner | source_database | consumer_database | share_type | createdate          | is_publicaccessible | share_acl | producer_account |           producer_namespace
-------------+-------------+-----------------+-------------------+------------+---------------------+---------------------+-----------+------------------+---------------------------------------
'salesshare' | 100         | dev             |                   | outbound   | 2020-12-09 01:22:54.| False               |           |   123456789012   | 13b8833d-17c6-4f16-8fe4-1a018f5ed00d
```

# SHOW PARAMETERS
<a name="r_SHOW_PARAMETERS"></a>

显示函数/过程的参数列表以及这些参数的部分相关信息。

每个输出行均包含 database\$1name、schema\$1name、procedure\$1name 或 function\$1name、parameter\$1name、ordinal\$1position、parameter\$1type（IN/OUT）、data\$1type、character\$1maximum\$1length、numeric\$1precision、numeric\$1scale 和 remarks 列。

## 所需的权限
<a name="r_SHOW_PARAMETERS-required-permissions"></a>

要查看 Redshift 架构中的函数/过程，当前用户必须满足下列条件之一：
+ 是超级用户
+ 是该函数的所有者
+ 已被授予父架构的 USAGE 权限以及该函数的 EXECUTE 权限

## 语法
<a name="r_SHOW_PARAMETERS-synopsis"></a>

```
SHOW PARAMETERS OF {FUNCTION| PROCEDURE}
[database_name.]schema_name.function_name(argtype [, ...] )
[LIKE 'filter_pattern'];
```

## 参数
<a name="r_SHOW_PARAMETERS-parameters"></a>

*database\$1name*  
包含要列出的函数的数据库的名称。

*schema\$1name*  
包含要列出的函数的架构的名称。

*filter\$1pattern*  
一个有效的 UTF-8 字符表达式，具有与表名称匹配的模式。LIKE 选项执行区分大小写的匹配，支持以下模式匹配元字符：      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_SHOW_PARAMETERS.html)

## 示例
<a name="r_SHOW_PARAMETERS-examples"></a>

以下示例显示过程 demo\$1db.demo\$1schema.f1 的参数：

```
SHOW PARAMETERS OF PROCEDURE demo_db.demo_schema.f1(VARCHAR, DECIMAL, DECIMAL, DECIMAL);
 database_name | schema_name | procedure_name |  parameter_name  | ordinal_position | parameter_type |          data_type          | character_maximum_length | numeric_precision | numeric_scale 
---------------+-------------+----------------+------------------+------------------+----------------+-----------------------------+--------------------------+-------------------+---------------
 demo_db       | demo_schema | f1             | operation        |                1 | IN             | character varying           |                       10 |                   |              
 demo_db       | demo_schema | f1             | value1           |                2 | IN             | numeric                     |                          |                18 |             0
 demo_db       | demo_schema | f1             | value2           |                3 | IN             | numeric                     |                          |                18 |             0
 demo_db       | demo_schema | f1             | result           |                4 | INOUT          | numeric                     |                          |                18 |             0
 demo_db       | demo_schema | f1             | operation_status |                5 | OUT            | character varying           |                       50 |                   |              
 demo_db       | demo_schema | f1             | calculation_time |                6 | OUT            | timestamp without time zone |                          |                   |              
 demo_db       | demo_schema | f1             | is_successful    |                7 | OUT            | boolean                     |                          |                   |
```

以下示例显示过程 demo\$1schema.f1 中名称以“val”开头的参数：

```
SHOW PARAMETERS OF PROCEDURE demo_schema.f1(VARCHAR, DECIMAL, DECIMAL, DECIMAL) like 'val%';
 database_name | schema_name | procedure_name | parameter_name | ordinal_position | parameter_type | data_type | character_maximum_length | numeric_precision | numeric_scale 
---------------+-------------+----------------+----------------+------------------+----------------+-----------+--------------------------+-------------------+---------------
 demo_db       | demo_schema | f1             | value1         |                2 | IN             | numeric   |                          |                18 |             0
 demo_db       | demo_schema | f1             | value2         |                3 | IN             | numeric   |                          |                18 |             0
```

以下示例显示函数 demo\$1schema.f2 的参数：

```
SHOW PARAMETERS OF FUNCTION demo_schema.f2(INT, VARCHAR, DECIMAL, DATE, TIMESTAMP, BOOLEAN);
 database_name | schema_name | function_name | parameter_name  | ordinal_position | parameter_type |          data_type          | character_maximum_length | numeric_precision | numeric_scale 
---------------+-------------+---------------+-----------------+------------------+----------------+-----------------------------+--------------------------+-------------------+---------------
 demo_db       | demo_schema | f2            |                 |                0 | RETURN         | character varying           |                       -1 |                   |              
 demo_db       | demo_schema | f2            | int_param       |                1 | IN             | integer                     |                          |                32 |             0
 demo_db       | demo_schema | f2            | varchar_param   |                2 | IN             | character varying           |                       -1 |                   |              
 demo_db       | demo_schema | f2            | decimal_param   |                3 | IN             | numeric                     |                          |                   |              
 demo_db       | demo_schema | f2            | date_param      |                4 | IN             | date                        |                          |                   |              
 demo_db       | demo_schema | f2            | timestamp_param |                5 | IN             | timestamp without time zone |                          |                   |              
 demo_db       | demo_schema | f2            | boolean_param   |                6 | IN             | boolean                     |                          |                   |
```

# SHOW POLICIES
<a name="r_SHOW_POLICIES"></a>

显示数据库中定义的行级别安全性（RLS）和动态数据掩蔽（DDM）策略，以及适用于特定关系的 RLS 和 DDM 策略。只有超级用户或在数据库中拥有 `sys:secadmin` 角色的用户才能查看这些策略的结果。

## 语法
<a name="r_SHOW_POLICIES-synopsis"></a>

```
SHOW { RLS | MASKING } POLICIES
[
    ON { database_name.schema_name.relation_name
       | schema_name.relation_name
       }
    [ FOR { user_name | ROLE role_name | PUBLIC } ]
  |
    FROM DATABASE database_name
]
[ LIMIT row_limit ];
```

## 参数
<a name="r_SHOW_POLICIES-parameters"></a>

*database\$1name*  
要显示其中策略的数据库的名称。

*schema\$1name*  
要显示其上附加的策略的关系的架构名称。

*relation\$1name*  
要显示其上附加的策略的关系的名称。

*user\$1name*  
已为其关系附加策略的用户的名称。

*role\$1name*  
已为其关系附加策略的角色的名称。

*row\$1limit*  
要返回的最大行数。*row\$1limit* 可以是 0–10000。

**注意**  
Amazon Redshift 联合身份验证权限目录支持显示已连接数据库之外的其他数据库中的策略。SHOW POLICIES 命令支持对数据仓库中所有带 Amazon Redshift 联合身份验证权限的数据库进行跨数据库查询

## 示例
<a name="r_SHOW_POLICIES-examples"></a>

以下命令显示已连接数据库的 RLS 策略。

```
SHOW RLS POLICIES;

  policy_name   | policy_alias |                           policy_atts                            |                                                                  policy_qual                                                                         | policy_enabled | policy_modified_by |    policy_modified_time    
----------------+--------------+------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+----------------+--------------------+----------------------------
 policy_america | rls_table    | [{"colname":"region","type":"character varying(10)"}]            | (("rls_table"."region" = CAST('USA' AS TEXT)) OR ("rls_table"."region" = CAST('CANADA' AS TEXT)) OR ("rls_table"."region" = CAST('Mexico' AS TEXT))) | t              | admin              | 2025-11-07 14:57:27
```

以下命令显示数据库“sales\$1db.finance-catalog”中的掩蔽策略；

```
SHOW MASKING POLICIES FROM DATABASE "sales_db@finance-catalog";

  policy_name  |                          input_columns                           |                                                  policy_expression                                                  | policy_modified_by |    policy_modified_time    
---------------+------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------+--------------------+----------------------------
 hash_credit   | [{"colname":"credit_card","type":"character varying(256)"}]      | [{"expr":"SHA2((\"masked_table\".\"credit_card\" + CAST('testSalt' AS TEXT)), CAST(256 AS INT4))","type":"text"}]   | admin              | 2025-11-07 16:05:54
 hash_username | [{"colname":"username","type":"character varying(256)"}]         | [{"expr":"SHA2((\"masked_table\".\"username\" + CAST('otherTestSalt' AS TEXT)), CAST(256 AS INT4))","type":"text"}] | admin              | 2025-11-07 16:07:08
(2 rows)
```

以下命令显示关系 sales\$1table 上附加的 RLS 策略；

```
SHOW RLS POLICIES ON sales_schema.sales_table;

  policy_name   | schema_name  | relation_name | relation_kind | grantor  |          grantee          | grantee_kind | is_policy_on | is_rls_on | rls_conjunction_type 
----------------+--------------+---------------+---------------+----------+---------------------------+--------------+--------------+-----------+----------------------
 policy_global  | sales_schema | sales_table   | table         | admin    | sales_analyst_role_global | role         | t            | t         | and
 policy_america | sales_schema | sales_table   | table         | admin    | sales_analyst_usa         | user         | t            | t         | and
```

以下命令显示数据库“sales\$1db.finance-catalog”中的关系 transaction\$1table 上附加的掩蔽策略。

```
SHOW MASKING POLICIES ON "sales_db@finance-catalog".sales_schema.transaction_table LIMIT 1;

  policy_name  | schema_name  |   relation_name   | relation_type | grantor  |         grantee          | grantee_type | priority |   input_columns   |   output_columns   
---------------+--------------+-------------------+---------------+----------+--------------------------+--------------+----------+-------------------+-------------------
 hash_username | sales_schema | transaction_table | table         | admin    | transaction_analyst_role | role         |      100 | ["user_name"]     | ["user_name"]
```

以下命令显示用户“IAMR:sales\$1analyst\$1usa”的数据库“sales\$1db.finance-catalog”中的关系 sales\$1table 上附加的 RLS 策略。

```
SHOW RLS POLICIES ON "sales_db@finance-catalog".sales_schema.sales_table FOR "IAMR:sales_analyst_usa";

  policy_name   | schema_name  | relation_name | relation_kind | grantor  |      grantee           | grantee_kind | is_policy_on | is_rls_on | rls_conjunction_type 
----------------+--------------+---------------+---------------+----------+------------------------+--------------+--------------+-----------+----------------------
 policy_america | sales_schema | sales_table   | table         | admin    | IAMR:sales_analyst_usa | user         | t            | t         | and
```

以下命令显示角色 transaction\$1analyst\$1role 的数据库“sales\$1db.finance-catalog”中的关系 transaction\$1table 上附加的 RLS 策略。

```
SHOW MASKING POLICIES ON sales_schema.transaction_table FOR ROLE transaction_analyst_role;

  policy_name  | schema_name  |   relation_name   | relation_type | grantor  |         grantee          | grantee_type | priority | input_columns | output_columns 
---------------+--------------+-------------------+---------------+----------+--------------------------+--------------+----------+---------------+----------------
 hash_username | sales_schema | transaction_table | table         | admin    | transaction_analyst_role | role         |      100 | ["user_name"] | ["user_name"]
```

# SHOW PROCEDURE
<a name="r_SHOW_PROCEDURE"></a>

显示给定存储过程的定义，包括其签名。您可以使用 SHOW PROCEDURE 的输出来重新创建存储过程。

## 语法
<a name="r_SHOW_PROCEDURE-synopsis"></a>

```
SHOW PROCEDURE sp_name [( [ [ argname ] [ argmode ] argtype [, ...] ] )]
```

## 参数
<a name="r_SHOW_PROCEDURE-parameters"></a>

 *sp\$1name*   
要显示的过程的名称。

*[argname] [ argmode] argtype*   
用于标识存储过程的输入参数类型。（可选）您可以包含完整的参数数据类型，包括 OUT 参数。如果存储过程名称是唯一的（即未重载），则此部分是可选的。

## 示例
<a name="r_SHOW_PROCEDURE-examples"></a>

以下示例显示 `test_spl2` 过程的定义。

```
show procedure test_sp2(int, varchar);
                                        Stored Procedure Definition
------------------------------------------------------------------------------------------------------------
CREATE OR REPLACE PROCEDURE public.test_sp2(f1 integer, INOUT f2 character varying, OUT character varying)
LANGUAGE plpgsql
AS $_$
DECLARE
out_var alias for $3;
loop_var int;
BEGIN
IF f1 is null OR f2 is null THEN
RAISE EXCEPTION 'input cannot be null';
END IF;
CREATE TEMP TABLE etl(a int, b varchar);
FOR loop_var IN 1..f1 LOOP
insert into etl values (loop_var, f2);
f2 := f2 || '+' || f2;
END LOOP;
SELECT INTO out_var count(*) from etl;
END;
$_$

(1 row)
```

# SHOW PROCEDURES
<a name="r_SHOW_PROCEDURES"></a>

显示架构中的过程列表以及这些列出对象的相关信息。

每个输出行均包含 `database_name`、`schema_name`、`procedure_name`、`number_of_arguments`、`argument_list`、`return_type` 和 remarks 列。

如果 SHOW PROCEDURES 命令返回的行数超过 10000，则该命令会引发错误。

## 所需的权限
<a name="r_SHOW_PROCEDURES-required-permissions"></a>

要查看 Redshift 架构中的过程，当前用户必须满足下列条件之一：
+ 是超级用户
+ 是过程的所有者
+ 已被授予父架构的 USAGE 权限以及该过程的 EXECUTE 权限

## 语法
<a name="r_SHOW_PROCEDURES-synopsis"></a>

```
SHOW PROCEDURES FROM SCHEMA
[database_name.]schema_name
[LIKE 'filter_pattern'] [LIMIT row_limit]
```

## 参数
<a name="r_SHOW_PROCEDURES-parameters"></a>

database\$1name  
包含要列出的过程的数据库的名称。

schema\$1name  
包含要列出的过程的架构的名称。

filter\$1pattern  
一个有效的 UTF-8 字符表达式，具有与过程名称匹配的模式。LIKE 选项执行区分大小写的匹配，支持以下模式匹配元字符：      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_SHOW_PROCEDURES.html)
请注意，filter\$1pattern 仅与过程名称匹配。

row\$1limit  
要返回的最大行数。*row\$1limit* 可以是 0–10000。

## 示例
<a name="r_SHOW_PROCEDURES-examples"></a>

以下示例显示架构 demo\$1db.demo\$1schema 中的过程：

```
SHOW PROCEDURES FROM SCHEMA demo_db.demo_schema;
 database_name | schema_name |  procedure_name   | number_of_arguments |                argument_list                 |                           return_type                            | remarks 
---------------+-------------+-------------------+---------------------+----------------------------------------------+------------------------------------------------------------------+---------
 demo_db       | demo_schema | f1                |                   4 | character varying, numeric, numeric, numeric | numeric, character varying, timestamp without time zone, boolean | 
 demo_db       | demo_schema | sp_get_result_set |                   2 | integer, refcursor                           | refcursor                                                        | 
 demo_db       | demo_schema | sp_process_data   |                   2 | numeric, numeric                             | numeric, character varying                                       |
```

以下示例显示架构 demo\$1schema 中名称以“data”结尾的过程：

```
SHOW PROCEDURES FROM SCHEMA demo_schema like '%data';
 database_name | schema_name | procedure_name  | number_of_arguments |  argument_list   |        return_type         | remarks 
---------------+-------------+-----------------+---------------------+------------------+----------------------------+---------
 demo_db       | demo_schema | sp_process_data |                   2 | numeric, numeric | numeric, character varying |
```

# SHOW SCHEMAS
<a name="r_SHOW_SCHEMAS"></a>

显示数据库中的架构列表以及一些架构属性。

每个输出行都包含数据库名称、架构名称、架构所有者、架构类型、架构 ACL、源数据库和架构选项。有关这些属性的更多信息，请参阅 [SVV\$1ALL\$1SCHEMAS](r_SVV_ALL_SCHEMAS.md)。

如果 SHOW SCHEMAS 命令可以生成超过 10000 个架构，则会返回错误。

## 所需的权限
<a name="r_SHOW_SCHEMAS-privileges"></a>

要查看 Amazon Redshift 表中的架构，当前用户必须满足以下条件之一：
+ 是超级用户。
+ 是架构的拥有者。
+ 获得对架构的 USAGE 权限。

## 语法
<a name="r_SHOW_SCHEMAS-synopsis"></a>

```
SHOW SCHEMAS FROM DATABASE database_name [LIKE 'filter_pattern'] [LIMIT row_limit ]
```

## 参数
<a name="r_SHOW_SCHEMAS-parameters"></a>

 *database\$1name*   
包含要列出的表的数据库的名称。  
要显示 AWS Glue Data Catalog 中的表，请指定（`awsdatacatalog`）作为数据库名称，并确保系统配置 `data_catalog_auto_mount` 设置为 `true`。有关更多信息，请参阅 [ALTER SYSTEM](r_ALTER_SYSTEM.md)。

 *filter\$1pattern*   
一个有效的 UTF-8 字符表达式，具有与架构名称匹配的模式。LIKE 选项执行区分大小写的匹配，支持以下模式匹配元字符：      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_SHOW_SCHEMAS.html)
如果 *filter\$1pattern* 不包含元字符，则模式仅表示字符串本身；在此情况下，LIKE 的行为与等于运算符相同。

 *row\$1limit*   
要返回的最大行数。*row\$1limit* 可以是 0–10000。

## 示例
<a name="r_SHOW_SCHEMAS-examples"></a>

以下示例显示了来自名为 `dev` 的 Amazon Redshift 数据库的架构。

```
SHOW SCHEMAS FROM DATABASE dev;

 database_name |     schema_name      | schema_owner | schema_type |         schema_acl          | source_database | schema_option 
---------------+----------------------+--------------+-------------+-----------------------------+-----------------+---------------
 dev           | pg_automv            |            1 | local       |                             |                 | 
 dev           | pg_catalog           |            1 | local       | jpuser=UC/jpuser~=U/jpuser  |                 | 
 dev           | public               |            1 | local       | jpuser=UC/jpuser~=UC/jpuser |                 | 
 dev           | information_schema   |            1 | local       | jpuser=UC/jpuser~=U/jpuser  |                 | 
 dev           | schemad79cd6d93bf043 |            1 | local       |                             |                 |
```

以下示例显示了名为 `awsdatacatalog` 的 AWS Glue Data Catalog 数据库中的架构。最大输出行数为 `5`。

```
SHOW SCHEMAS FROM DATABASE awsdatacatalog LIMIT 5;

 database_name  |     schema_name      | schema_owner | schema_type | schema_acl | source_database | schema_option 
----------------+----------------------+--------------+-------------+------------+-----------------+---------------
 awsdatacatalog | 000_too_many_glue_db |              | EXTERNAL    |            |                 | 
 awsdatacatalog | 123_default          |              | EXTERNAL    |            |                 | 
 awsdatacatalog | adhoc                |              | EXTERNAL    |            |                 | 
 awsdatacatalog | all_shapes_10mb      |              | EXTERNAL    |            |                 | 
 awsdatacatalog | all_shapes_1g        |              | EXTERNAL    |            |                 |
```

# SHOW TABLE
<a name="r_SHOW_TABLE"></a>

显示表的定义，包括表属性、表约束、列属性、列排序规则和列约束。您可以使用 SHOW TABLE 语句的输出来重新创建表。

有关表创建的更多信息，请参阅[CREATE TABLE](r_CREATE_TABLE_NEW.md)。

## 语法
<a name="r_SHOW_TABLE-synopsis"></a>

```
SHOW TABLE [schema_name.]table_name 
```

## 参数
<a name="r_SHOW_TABLE-parameters"></a>

 *schema\$1name*   
（可选）相关 schema 的名称。

 *table\$1name*   
要显示的表的名称。

## 示例
<a name="r_SHOW_TABLE-examples"></a>

以下是表 `sales` 的 SHOW TABLE 输出示例。

```
show table sales;
```

```
CREATE TABLE public.sales (
salesid integer NOT NULL ENCODE az64,
listid integer NOT NULL ENCODE az64 distkey,
sellerid integer NOT NULL ENCODE az64,
buyerid integer NOT NULL ENCODE az64,
eventid integer NOT NULL ENCODE az64,
dateid smallint NOT NULL,
qtysold smallint NOT NULL ENCODE az64,
pricepaid numeric(8,2) ENCODE az64,
commission numeric(8,2) ENCODE az64,
saletime timestamp without time zone ENCODE az64
)
DISTSTYLE KEY SORTKEY ( dateid );
```

以下是 schema `public` 中的表 `category` 的 SHOW TABLE 输出示例。数据库的排序规则为 CASE\$1SENSITIVE。

```
show table public.category;
```

```
CREATE TABLE public.category (
catid smallint NOT NULL distkey,
catgroup character varying(10) ENCODE lzo COLLATE case_sensitive,
catname character varying(10) ENCODE lzo COLLATE case_sensitive,
catdesc character varying(50) ENCODE lzo COLLATE case_sensitive
) 
DISTSTYLE KEY SORTKEY ( catid );
```

以下示例将使用主键创建表 `foo`。

```
create table foo(a int PRIMARY KEY, b int);
```

SHOW TABLE 结果将显示 create 语句，以及 `foo` 表的所有属性。

```
show table foo;
```

```
CREATE TABLE public.foo ( 
a integer NOT NULL ENCODE az64, 
b integer ENCODE az64, PRIMARY KEY (a) 
) 
DISTSTYLE AUTO;
```

在此示例中，我们创建了一个表，其中列 `a` 继承数据库的默认 CASE\$1SENSITIVE 排序规则，而列 `b` 和 `c` 则显式设置为 CASE\$1INSENSITIVE 排序规则。

```
CREATE TABLE public.foo (
a CHAR, 
b VARCHAR(10) COLLATE CASE_INSENSITIVE, 
c SUPER COLLATE CASE_INSENSITIVE
);
```

SHOW TABLE 结果将显示 create 语句，以及 `foo` 表的所有属性。

```
show table public.foo;
```

```
CREATE TABLE public.foo (
a character(1) ENCODE lzo COLLATE case_sensitive,
b character varying(10) ENCODE lzo COLLATE case_insensitive,
c super COLLATE case_insensitive
)
DISTSTYLE AUTO;
```

# SHOW TABLES
<a name="r_SHOW_TABLES"></a>

显示架构中表的列表以及一些表属性。

每个输出行由数据库名称、架构名称、表名、表类型、表 ACL、备注、表所有者、上次更改时间、上次修改时间、dist\$1style 和表子类型组成。有关这些属性的更多信息，请参阅 [SVV\$1ALL\$1TABLES](r_SVV_ALL_TABLES.md)。

修改时间戳和更改时间戳可能会比表更新滞后约 20 分钟。

如果由 SHOW TABLES 命令生成的表超过 10000 个，则会返回错误。

## 所需的权限
<a name="r_SHOW_TABLES-privileges"></a>

要查看 Amazon Redshift 架构中的表，当前用户必须满足以下条件之一：
+ 是超级用户。
+ 是该表的拥有者。
+ 获得对父架构的 USAGE 权限，并获得对表的 SELECT 权限或对该表中任何列的 SELECT 权限。

## 语法
<a name="r_SHOW_TABLES-synopsis"></a>

```
SHOW TABLES FROM SCHEMA database_name.schema_name [LIKE 'filter_pattern'] [LIMIT row_limit ]
```

## 参数
<a name="r_SHOW_TABLES-parameters"></a>

 *database\$1name*   
包含要列出的表的数据库的名称。  
要显示 AWS Glue Data Catalog 中的表，请指定（`awsdatacatalog`）作为数据库名称，并确保系统配置 `data_catalog_auto_mount` 设置为 `true`。有关更多信息，请参阅 [ALTER SYSTEM](r_ALTER_SYSTEM.md)。

 *schema\$1name*   
包含要列出的表的架构的名称。  
要显示 AWS Glue Data Catalog 表，请提供 AWS Glue 数据库名称作为架构名称。

 *filter\$1pattern*   
一个有效的 UTF-8 字符表达式，具有与表名称匹配的模式。LIKE 选项执行区分大小写的匹配，支持以下模式匹配元字符：      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_SHOW_TABLES.html)
如果 *filter\$1pattern* 不包含元字符，则模式仅表示字符串本身；在此情况下，LIKE 的行为与等于运算符相同。

 *row\$1limit*   
要返回的最大行数。*row\$1limit* 可以是 0–10000。

## 示例
<a name="r_SHOW_TABLES-examples"></a>

```
SHOW TABLES FROM SCHEMA s1;

 database_name | schema_name |    table_name     | table_type |              table_acl              | remarks | owner |     last_altered_time      |     last_modified_time     | dist_style |   table_subtype   
---------------+-------------+-------------------+------------+-------------------------------------+---------+-------+----------------------------+----------------------------+------------+-------------------
 dev           | s1          | late_binding_view | VIEW       | alice=arwdRxtDPA/alice~bob=d/alice  |         | alice |                            |                            |            | LATE BINDING VIEW
 dev           | s1          | manual_mv         | VIEW       | alice=arwdRxtDPA/alice~bob=P/alice  |         | alice |                            |                            |            | MATERIALIZED VIEW
 dev           | s1          | regular_view      | VIEW       | alice=arwdRxtDPA/alice~bob=r/alice  |         | alice |                            |                            |            | REGULAR VIEW
 dev           | s1          | test_table        | TABLE      | alice=arwdRxtDPA/alice~bob=rw/alice |         | alice | 2025-11-18 15:52:00.010452 | 2025-11-18 15:44:34.856073 | AUTO (ALL) | REGULAR TABLE
```

```
SHOW TABLES FROM SCHEMA dev.s1 LIKE '%view' LIMIT 1;

 database_name | schema_name |    table_name     | table_type |              table_acl               | remarks | owner | last_altered_time | last_modified_time | dist_style |   table_subtype   
---------------+-------------+-------------------+------------+--------------------------------------+---------+-------+-------------------+--------------------+------------+-------------------
 dev           | s1          | late_binding_view | VIEW       | {alice=arwdRxtDPA/alice,bob=d/alice} |         | alice |                   |                    |            | LATE BINDING VIEW
```

# SHOW TEMPLATE
<a name="r_SHOW_TEMPLATE"></a>

显示模板的完整定义，包括完全限定名称（数据库、架构和模板名称）和所有参数。输出是一个有效的 CREATE TEMPLATE 语句，可用于重新创建模板或创建经过修改的类似模板。

有关模板创建的更多信息，请参阅 [CREATE TEMPLATE](r_CREATE_TEMPLATE.md)。

## 所需的权限
<a name="r_SHOW_TEMPLATE-privileges"></a>

要查看模板定义，您必须拥有以下其中一项：
+ 超级用户权限
+ 对模板拥有 USAGE 权限，并对包含模板的架构拥有 USAGE 权限

## 语法
<a name="r_SHOW_TEMPLATE-synopsis"></a>

```
SHOW TEMPLATE [database_name.][schema_name.]template_name;
```

## 参数
<a name="r_SHOW_TEMPLATE-parameters"></a>

 *database\$1name*   
（可选）在其中创建模板的数据库的名称。如果未指定，则使用当前数据库。

 *schema\$1name*   
（可选）在其中创建模板的架构的名称。如果未指定，则在当前搜索路径中搜索模板。

 *template\$1name*   
模板名称。

## 示例
<a name="r_SHOW_TEMPLATE-examples"></a>

下面是模板 `test_template` 的 SHOW TEMPLATE 输出的示例：

```
CREATE TEMPLATE test_template FOR COPY AS NOLOAD DELIMITER ',' ENCODING UTF16 ENCRYPTED;
```

```
SHOW TEMPLATE test_template;

CREATE OR REPLACE TEMPLATE dev.public.test_template FOR COPY AS ENCRYPTED NOLOAD ENCODING UTF16 DELIMITER ',';
```

以下示例在架构 `demo_schema` 中创建模板 `demo_template`。

```
CREATE OR REPLACE TEMPLATE demo_schema.demo_template FOR COPY AS
ACCEPTANYDATE ACCEPTINVCHARS DATEFORMAT 'DD-MM-YYYY' EXPLICIT_IDS ROUNDEC
TIMEFORMAT  AS 'DD.MM.YYYY HH:MI:SS' TRUNCATECOLUMNS NULL  AS 'null_string';
```

```
SHOW TEMPLATE demo_schema.demo_template;

CREATE OR REPLACE TEMPLATE dev.demo_schema.demo_template FOR COPY AS TRUNCATECOLUMNS NULL 'null_string' EXPLICIT_IDS TIMEFORMAT 'DD.MM.YYYY HH:MI:SS' ACCEPTANYDATE ROUNDEC ACCEPTINVCHARS DATEFORMAT 'DD-MM-YYYY';
```

# SHOW TEMPLATES
<a name="r_SHOW_TEMPLATES"></a>

显示架构中模板的列表及其属性。

每个输出行由模板名称、模板 ID、模板类型、模板所有者、数据库名称、架构名称、创建时间、上次修改时间和上次修改者组成。

有关完整的模板详细信息，包括模板参数，请参阅 [SYS\$1REDSHIFT\$1TEMPLATE](SYS_REDSHIFT_TEMPLATE.md)。

## 所需的权限
<a name="r_SHOW_TEMPLATES-privileges"></a>

要查看 Amazon Redshift 架构中的模板，您必须拥有以下其中一项：
+ 超级用户权限
+ 对包含模板的架构拥有 USAGE 权限

## 语法
<a name="r_SHOW_TEMPLATES-synopsis"></a>

```
SHOW TEMPLATES FROM SCHEMA [database_name.]schema_name [LIKE 'filter_pattern'] [LIMIT row_limit ];
```

## 参数
<a name="r_SHOW_TEMPLATES-parameters"></a>

 *database\$1name*   
（可选）数据库的名称，该数据库包含要列出的模板。如果未指定，则使用当前数据库。

 *schema\$1name*   
架构的名称，该架构包含要列出的模板。

 *filter\$1pattern*   
（可选）一个有效的 UTF-8 字符表达式，具有与模板名称匹配的模式。LIKE 选项执行区分大小写的匹配，支持以下模式匹配元字符：      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_SHOW_TEMPLATES.html)
如果 *filter\$1pattern* 不包含元字符，则模式仅表示字符串本身；在此情况下，LIKE 的行为与等于运算符相同。

 *row\$1limit*   
要返回的最大行数。有效范围为 0 到集群上的模板限制（默认值为 1000）。

## 示例
<a name="r_SHOW_TEMPLATES-examples"></a>

```
SHOW TEMPLATES FROM SCHEMA s1;

 template_name          | template_id | template_type | template_owner | database_name | schema_name |        create_time         |     last_modified_time     | last_modified_by
------------------------+-------------+---------------+----------------+---------------+-------------+----------------------------+----------------------------+------------------
 template_maxerror      |      107685 | COPY          | alice          | dev           | s1          | 2025-12-16 19:31:10.514076 | 2025-12-16 19:31:10.514076 |              100
 json_template          |      107687 | COPY          | alice          | dev           | s1          | 2025-12-16 19:31:33.229566 | 2025-12-16 19:31:33.229567 |              100
 noload_template        |      107686 | COPY          | alice          | dev           | s1          | 2025-12-16 19:31:17.370547 | 2025-12-16 19:31:17.370547 |              100
 csv_delimiter_template |      107688 | COPY          | alice          | dev           | s1          | 2025-12-16 19:31:42.354044 | 2025-12-16 19:31:42.354045 |              100
```

```
SHOW TEMPLATES FROM SCHEMA dev.s1 LIKE '%template' LIMIT 1;

 template_name  | template_id | template_type | template_owner | database_name | schema_name |        create_time         |     last_modified_time     | last_modified_by 
-----------------+-------------+---------------+----------------+---------------+-------------+----------------------------+----------------------------+------------------
 noload_template |      107686 | COPY          | alice          | dev           | s1          | 2025-12-16 19:31:17.370547 | 2025-12-16 19:31:17.370547 |              100
```

# SHOW VIEW
<a name="r_SHOW_VIEW"></a>

显示视图的定义，包括实体化视图和后期绑定视图的定义。您可以使用 SHOW VIEW 语句的输出来重新创建视图。

## 语法
<a name="r_SHOW_VIEW-synopsis"></a>

```
SHOW VIEW [schema_name.]view_name 
```

## 参数
<a name="r_SHOW_VIEW-parameters"></a>

 *schema\$1name*   
（可选）相关 schema 的名称。

 *view\$1name*   
要显示的视图的名称。

## 示例
<a name="r_SHOW_VIEW-examples"></a>

 以下是视图 `LA_Venues_v` 的视图定义。

```
create view LA_Venues_v as select * from venue where venuecity='Los Angeles';
```

以下是前面定义的视图的 SHOW VIEW 命令和输出示例。

```
show view LA_Venues_v;
```

```
SELECT venue.venueid,
venue.venuename,
venue.venuecity,
venue.venuestate,
venue.venueseats
FROM venue WHERE ((venue.venuecity)::text = 'Los Angeles'::text);
```

以下是 schema `public` 中的视图 `public.Sports_v` 的视图定义。

```
create view public.Sports_v as select * from category where catgroup='Sports';
```

以下是前面定义的视图的 SHOW VIEW 命令和输出示例。

```
show view public.Sports_v;
```

```
SELECT category.catid,
category.catgroup,
category.catname,
category.catdesc
FROM category WHERE ((category.catgroup)::text = 'Sports'::text);
```

# START TRANSACTION
<a name="r_START_TRANSACTION"></a>

BEGIN 函数的同义词。

请参阅 [BEGIN](r_BEGIN.md)。

# TRUNCATE
<a name="r_TRUNCATE"></a>

删除表中的所有行，而不执行表扫描：此操作是非限定的 DELETE 操作的替代方法，其速度更快。要运行 TRUNCATE 命令，您必须对表拥有 TRUNCATE 权限，是表的所有者，或者是超级用户。要授予截断表的权限，请使用 [GRANT](r_GRANT.md) 命令。

TRUNCATE 的效率要比 DELETE 高很多，不需要 VACUUM 和 ANALYZE。不过请注意，TRUNCATE 在其运行的事务中提交事务。

## 语法
<a name="r_TRUNCATE-synopsis"></a>

```
TRUNCATE [ TABLE ] table_name
```

该命令也适用于实体化视图。

```
TRUNCATE materialized_view_name
```

## 参数
<a name="r_TRUNCATE-parameters"></a>

TABLE   
可选关键字。

 *table\$1name*   
一个临时或永久表。只有表所有者或超级用户可以截断表。  
您可以截断任何表，包括在外键约束中引用的表。  
在截断表后，无需对表执行 vacuum 操作。

 *materialized\$1view\$1name*   
实体化视图。  
您可以截断用于[流式摄取到实体化视图](materialized-view-streaming-ingestion.md)的实体化视图。

## 使用说明
<a name="r_TRUNCATE_usage_notes"></a>
+  TRUNCATE 命令提交运行该命令的事务；因此，您无法回滚 TRUNCATE 操作，TRUNCATE 命令可能在提交自身时提交其他操作。
+ TRUNCATE 操作在连接到以下任何一项的 Amazon Redshift 流式传输实体化视图上运行时，将持有排他锁：
  +  Amazon Kinesis 数据流 
  +  Amazon Managed Streaming for Apache Kafka 主题 
  +  支持的外部流，例如 Confluent Cloud Kafka 主题 

  有关更多信息，请参阅 [流式摄取到实体化视图](materialized-view-streaming-ingestion.md)。

## 示例
<a name="r_TRUNCATE-examples"></a>

使用 TRUNCATE 命令可以删除 CATEGORY 表中的所有行：

```
truncate category;
```

尝试回滚 TRUNCATE 操作：

```
begin;

truncate date;

rollback;

select count(*) from date;
count
-------
0
(1 row)
```

DATE 表在 ROLLBACK 命令后保留为空，因为已自动提交 TRUNCATE 命令。

以下示例使用 TRUNCATE 命令从实体化视图中删除所有行。

```
truncate my_materialized_view;
```

此命令会删除实体化视图中的所有记录，并保持实体化视图及其架构不变。在查询中，实体化视图名称是一个示例。

# UNLOAD
<a name="r_UNLOAD"></a>


|  | 
| --- |
| 从 2025 年 4 月 30 日起，COPY 和 UNLOAD 命令的客户端加密将不再向新客户开放。如果您在 2025 年 4 月 30 日之前的 12 个月内将客户端加密与 COPY 和 UNLOAD 命令结合使用，则在 2026 年 4 月 30 日之前，可以继续将客户端加密与 COPY 和 UNLOAD 命令结合使用。2026 年 4 月 30 日之后，您无法使用客户端加密进行 COPY 和 UNLOAD。我们建议您尽快切换到使用客户端加密进行 COPY 和 UNLOAD。如果您已经在使用客户端加密进行 COPY 和 UNLOAD，则没有任何变化，您可以在不更改查询的情况下继续使用它。有关 COPY 和 UNLOAD 的加密的更多信息，请参阅下面的 ENCRYPTED 参数。 | 

使用 Amazon S3 服务器端加密 (SSE-S3) 功能将查询结果卸载到 Amazon S3 上的一个或多个文本文件、JSON 或 Apache Parquet 文件中。还可以指定具有 AWS Key Management Service 密钥的服务器端加密（SSE-KMS）。

预设情况下，卸载文件的格式为管道符分隔 ( `|` ) 的文本。

您可以通过设置 MAXFILESIZE 参数来管理 Amazon S3 上文件的大小，并可通过扩展对文件数进行管理。确保将 S3 IP 范围添加到您的允许列表中。要了解有关所需 S3 IP 范围的更多信息，请参阅[网络隔离](https://docs.aws.amazon.com//redshift/latest/mgmt/security-network-isolation.html#network-isolation)。

现在，您可以将 Amazon Redshift 查询的结果卸载到 Apache Parquet 中的 Amazon S3 数据湖，Apache Parquet 是一种用于分析的高效开放列式存储格式。与文本格式相比，Parquet 格式的卸载速度提高了 2 倍，并且在 Amazon S3 中耗用的存储量减少了 6 倍。这使您能够以开放格式将在 Amazon S3 中完成的数据转换和数据扩充保存到 Amazon S3 数据湖中。然后，您可以使用 Redshift Spectrum 和其它 AWS 服务（例如 Amazon Athena、Amazon EMR 和 Amazon SageMaker AI）分析您的数据。

有关使用 UNLOAD 命令的更多信息和示例场景，请参阅[在 Amazon Redshift 中卸载数据](c_unloading_data.md)。

## 所需的特权和权限
<a name="r_UNLOAD-permissions"></a>

要成功执行 UNLOAD 命令，至少需要对数据库中的数据具有 SELECT 权限以及写入 Amazon S3 位置的权限。有关访问 UNLOAD 命令的 AWS 资源的权限的信息，请参阅[访问其他 AWS 资源的权限](copy-usage_notes-access-permissions.md)。

要应用最低权限，请遵循以下建议，仅根据需要向运行该命令的用户授予权限。
+ 用户必须对数据具有 SELECT 权限。有关如何限制数据库权限的信息，请参阅 [GRANT](r_GRANT.md)。
+ 用户需要具有权限才能代入 IAM 角色，以写入您 AWS 账户中的 Amazon S3 存储桶。要限制数据库用户代入角色的访问权限，请参阅《Amazon Redshift 管理指南》**中的[限制对 IAM 角色的访问](https://docs.aws.amazon.com/redshift/latest/mgmt/authorizing-redshift-service-database-users.html)。
+ 用户需要具有访问 Amazon S3 存储桶的权限。要使用 Amazon S3 存储桶策略限制权限，请参阅《Amazon Simple Storage Service 用户指南》**中的 [Amazon S3 的存储桶策略](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-policies.html)。

## 语法
<a name="r_UNLOAD-synopsis"></a>

```
UNLOAD ('select-statement')
TO 's3://object-path/name-prefix'
authorization
[ option, ...] 

where authorization is
IAM_ROLE { default | 'arn:aws:iam::<AWS 账户-id-1>:role/<role-name>[,arn:aws:iam::<AWS 账户-id-2>:role/<role-name>][,...]' }
            
where option is
| [ FORMAT [ AS ] ] CSV | PARQUET | JSON
| PARTITION BY ( column_name [, ... ] ) [ INCLUDE ]
| MANIFEST [ VERBOSE ]
| HEADER
| DELIMITER [ AS ] 'delimiter-char'
| FIXEDWIDTH [ AS ] 'fixedwidth-spec'
| ENCRYPTED [ AUTO ]
| BZIP2
| GZIP
| ZSTD
| ADDQUOTES
| NULL [ AS ] 'null-string'
| ESCAPE
| ALLOWOVERWRITE
| CLEANPATH
| PARALLEL [ { ON | TRUE } | { OFF | FALSE } ]
| MAXFILESIZE [AS] max-size [ MB | GB ]
| ROWGROUPSIZE [AS] size [ MB | GB ]
| REGION [AS] 'aws-region' }
| EXTENSION 'extension-name'
```

## 参数
<a name="unload-parameters"></a>

('*select-statement*')   
SELECT 查询。卸载查询的结果。大多数情况下，通过在查询中指定 ORDER BY 子句来按排序顺序卸载数据是值得的。这种方法可以节省重新加载数据时对数据进行排序所需的时间。  
必须用单引号将查询括起来，如下所示：  

```
('select * from venue order by venueid')
```
如果查询包含引号（例如，用引号将文本值引起来），则将文本放在两组单引号之间—您还必须用单引号将查询引起来：  

```
('select * from venue where venuestate=''NV''')
```

TO 's3://*object-path/name-prefix*'  
Amazon S3 上的位置的完整路径（包括桶名称），Amazon Redshift 会将输出文件对象（如果指定 MANIFEST，则包括清单文件）写入到该位置。对象名将带有 *name-prefix* 前缀。如果使用 `PARTITION BY`，则会根据需要自动将正斜杠 (/) 添加到 *name-prefix* 值的末尾。为了增强安全性，UNLOAD 使用 HTTPS 连接来连接到 Amazon S3。默认情况下，UNLOAD 为每个切片写入一个或多个文件。UNLOAD 会将一个分片编号和一个分段编号附加到指定名称前缀，如下所示：  
`<object-path>/<name-prefix><slice-number>_part_<part-number>`.   
如果指定了 MANIFEST，则会按以下格式写入清单文件：  
`<object_path>/<name_prefix>manifest`.   
如果将 PARALLEL 指定为 OFF，则按如下方式写入数据文件：  
`<object_path>/<name_prefix><part-number>`.   
UNLOAD 会使用 Amazon S3 服务器端加密 (SSE) 自动创建加密文件，如果使用 MANIFEST，还将包括清单文件。COPY 命令在加载操作期间会自动读取服务器端加密文件。您可以使用 Amazon S3 控制台或 API 以透明方式从桶下载服务器端加密文件。有关更多信息，请参阅[使用服务器端加密保护数据](https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html)。  
当 Amazon S3 桶与 Amazon Redshift 数据库不在同一个 AWS 区域时，需要 REGION。

*authorization*、\$1  
UNLOAD 命令需要向 Amazon S3 写入数据的授权。UNLOAD 命令的授权参数与 COPY 命令相同。有关更多信息，请参阅 COPY 命令语法参考中的 [授权参数](copy-parameters-authorization.md)。

IAM\$1ROLE \$1 default \$1 ‘arn:aws:iam::*<AWS 账户-id-1>*:role/*<role-name>*'  <a name="unload-iam"></a>
使用默认关键字让 Amazon Redshift 使用 IAM 角色，该角色设置为默认值并在 UNLOAD 命令运行时与集群关联。  
使用 IAM 角色的 Amazon 资源名称（ARN），您的集群使用该角色进行身份验证和授权。如果您指定 IAM\$1ROLE，则无法使用 ACCESS\$1KEY\$1ID 和 SECRET\$1ACCESS\$1KEY、SESSION\$1TOKEN 或 CREDENTIALS。IAM\$1ROLE 可以链接起来。有关更多信息，请参阅《Amazon Redshift 管理指南》**中的[链接 IAM 角色](https://docs.aws.amazon.com/redshift/latest/mgmt/authorizing-redshift-service.html#authorizing-redshift-service-chaining-roles)。

[ FORMAT [AS] ] CSV \$1 PARQUET \$1 JSON  <a name="unload-csv"></a>
用于指定卸载格式以覆盖默认格式的关键词。  
使用 CSV 时，使用逗号 (,) 字符作为默认分隔符卸载到 CSV 格式的文本文件。如果某个字段包含分隔符、双引号、换行符或回车符，则卸载文件中的该字段会用双引号引起来。数据字段中的双引号由一个额外的双引号转义。当卸载零行时，Amazon Redshift 可能会写入空的 Amazon S3 对象。  
使用 PARQUET 时，卸载到 Apache Parquet 1.0 版本格式的文件。默认情况下，每个行组都使用 SNAPPY 压缩进行压缩。有关 Apache Parquet 格式的更多信息，请参阅 [Parquet](https://parquet.apache.org/)。  
当 JSON 卸载到 JSON 文件时，其中每行都包含一个 JSON 对象，表示查询结果中的完整记录。当查询结果包含 SUPER 列时，Amazon Redshift 支持编写嵌套 JSON。要创建有效的 JSON 对象，查询中每个列的名称必须唯一。在 JSON 文件中，布尔值将卸载为 `t` 或 `f`，并且 NULL 值卸载为 `null`。当卸载零行时，Amazon Redshift 不写入 Amazon S3 对象。  
关键字 FORMAT 和 AS 是可选的。不能将 CSV 与 ESCAPE、FIXEDWIDTH 或 ADDQUOTES 一起使用。您不能将 PARQUET 与 DELIMITER、FIXEDWIDTH、ADDQUOTES、ESCAPE、NULL AS、HEADER、GZIP、BZIP2 或 ZSTD 一起使用。只有使用 AWS Key Management Service 密钥的服务器端加密 (SSE-KMS) 支持带有 ENCRYPTED 的 PARQUET。您不能将 JSON 与 DELIMITER、HEADER、FIXEDWIDTH、ADDQUOTES、ESCAPE 或 NULL AS 一起使用。

PARTITION BY ( *column\$1name* [, ... ] ) [INCLUDE]  <a name="unload-partitionby"></a>
指定卸载操作的分区键。UNLOAD 按照 Apache Hive 约定，根据分区键值自动将输出文件分区到分区文件夹中。例如，属于 2019 分区年和 9 月份的 Parquet 文件具有以下前缀：`s3://amzn-s3-demo-bucket/my_prefix/year=2019/month=September/000.parquet`。  
*column\$1name* 的值必须是正在卸载的查询结果中的列。  
如果指定 PARTITION BY 与 INCLUDE 选项，则不会从卸载的文件中删除分区列。  
Amazon Redshift 不支持 PARTITION BY 子句中的字符串文本。

MANIFEST [ VERBOSE ]  
创建一个清单文件，其中明确列出由 UNLOAD 过程创建的数据文件的详细信息。清单是一个 JSON 格式的文本文件，其中列出写入到 Amazon S3 的每个文件的 URL。  
如果使用 VERBOSE 选项指定 MANIFEST，则清单包含以下详细信息：  
+ 列名和数据类型，对于 CHAR、VARCHAR 或 NUMERIC 数据类型，还包含每列的维度。对于 CHAR 和 VARCHAR 数据类型，维度是长度。对于 DECIMAL 或 NUMERIC 数据类型，维度是精度和小数位数。
+ 已卸载到每个文件的行计数。如果指定了 HEADER 选项，则行计数包括标题行。
+ 卸载的所有文件的总文件大小以及卸载到所有文件的总行数。如果指定了 HEADER 选项，则行计数包括标题行。
+ 作者。作者始终是“Amazon Redshift”。
您只能在 MANIFEST 之后指定 VERBOSE。  
清单文件将采用与卸载文件相同的 Amazon S3 路径前缀，按照 `<object_path_prefix>manifest` 的格式写入。例如，如果 UNLOAD 指定 Amazon S3 路径前缀“`s3://amzn-s3-demo-bucket/venue_`”，则清单文件位置为“`s3://amzn-s3-demo-bucket/venue_manifest`”。

HEADER  
在每个输出文件的顶部添加包含列名称的标题行。文本转换选项（如 CSV、DELIMITER、ADDQUOTES 和 ESCAPE）也适用于标题行。您不能将 HEADER 与 FIXEDWIDTH 一起使用。

DELIMITER AS '*delimiter\$1character*'  
指定用于在输出文件中分隔字段的单个 ASCII 字符，如管道字符 (\$1)、逗号 (,) 或制表符 (\$1t)。文本文件的默认分隔符是竖线字符。CSV 文件的默认分隔符是逗号字符。AS 关键字是可选的。您不能将 DELIMITER 与 FIXEDWIDTH 一起使用。如果数据包含分隔符，您需要指定 ESCAPE 选项来转义分隔符，或者使用 ADDQUOTES 用双引号将数据括起来。或者，指定一个数据中不包含的分隔符。

FIXEDWIDTH '*fixedwidth\$1spec*'  
将数据卸载到一个文件，其中每个列的宽度均为固定长度，而不是由分隔符隔开。*fixedwidth\$1spec* 是一个字符串，用于指定列数和列宽。AS 关键字是可选的。由于 FIXEDWIDTH 不会截断数据，因此 UNLOAD 语句中每个列的规格必须至少为该列最长条目的长度。*fixedwidth\$1spec* 的格式如下：  

```
'colID1:colWidth1,colID2:colWidth2, ...'
```
您不能将 FIXEDWIDTH 与 DELIMITER 或 HEADER 一起使用。

ENCRYPTED [AUTO] (加密 [自动])  <a name="unload-parameters-encrypted"></a>
指定使用 Amazon S3 服务器端加密对 Amazon S3 上的输出文件进行加密。如果指定了 MANIFEST，也会加密清单文件。有关更多信息，请参阅 [卸载加密的数据文件](t_unloading_encrypted_files.md)。如果不指定 ENCRYPTED 参数，UNLOAD 会使用 AWS 托管的加密密钥进行 Amazon S3 服务器端加密 (SSE-S3)，自动创建加密文件。  
对于 ENCRYPTED，您可能希望使用 AWS KMS 密钥进行服务器端加密 (SSE-KMS) 卸载到 Amazon S3。如果是这样，请使用 [KMS_KEY_ID](#unload-parameters-kms-key-id) 参数提供密钥 ID。[使用 CREDENTIALS 参数](copy-parameters-authorization.md#copy-credentials) 参数不能与 KMS\$1KEY\$1ID 参数配合使用。如果使用 KMS\$1KEY\$1ID 对数据运行 UNLOAD 命令，则可以对同一数据执行 COPY 操作，而无需指定密钥。  
如果使用 ENCRYPTED AUTO，则 UNLOAD 命令将提取目标 Amazon S3 桶属性上的默认 AWS KMS 加密密钥，并使用 AWS KMS 密钥加密写入 Amazon S3 的文件。如果桶没有默认的 AWS KMS 加密密钥，UNLOAD 会使用 AWS 托管的加密密钥进行 Amazon Redshift 服务器端加密 (SSE-S3) 以自动创建加密文件。您不能将此选项与 KMS\$1KEY\$1ID、MASTER\$1SYMMETRIC\$1KEY 或包含 master\$1symmetric\$1key 的 CREDENTIALS 一起使用。

KMS\$1KEY\$1ID '*key-id*'  <a name="unload-parameters-kms-key-id"></a>
指定用于在 Amazon S3 上加密数据文件的 AWS Key Management Service（AWS KMS）密钥的密钥 ID。有关更多信息，请参阅[什么是 AWS Key Management Service？](https://docs.aws.amazon.com/kms/latest/developerguide/overview.html) 如果指定 KMS\$1KEY\$1ID，您还必须指定 [ENCRYPTED](#unload-parameters-encrypted) 参数。如果指定 KMS\$1KEY\$1ID，则不能使用 CREDENTIALS 参数进行身份验证，而应使用 [使用 IAM\$1ROLE 参数](copy-parameters-authorization.md#copy-iam-role) 或 [使用 ACCESS\$1KEY\$1ID 和 SECRET\$1ACCESS\$1KEY 参数](copy-parameters-authorization.md#copy-access-key-id)。

BZIP2   
对于每个切片，将数据卸载到一个或多个 bzip2 压缩的文件。将为每个生成的文件附加 `.bz2` 扩展名。

GZIP   
对于每个切片，将数据卸载到一个或多个 gzip 压缩的文件。将为每个生成的文件附加 `.gz` 扩展名。

ZSTD   
对于每个切片，将数据卸载到一个或多个 Zstandard 压缩的文件。将为每个生成的文件附加 `.zst` 扩展名。

ADDQUOTES   
使用引号将每个卸载的数据字段括起来，以便 Amazon Redshift 能够自行卸载包含分隔符自身的数据值。例如，如果分隔符为逗号，则可以成功卸载并重新加载以下数据：  

```
 "1","Hello, World" 
```
如果不添加引号，则将字符串 `Hello, World` 解析为两个单独的字段。  
某些输出格式不支持 ADDQUOTES。  
在使用 ADDQUOTES 的情况下，如果重新加载数据，则必须在 COPY 中指定 REMOVEQUOTES。

NULL AS '*null-string*'  
指定表示卸载文件中的 null 值的字符串。如果使用此选项，所有输出文件将包含指定字符串来替代在选定数据中找到的所有 null 值。如果未指定此选项，则 null 值将卸载为：  
+ 零长度字符串（对于分隔的输出） 
+ 空格字符串（对于固定宽度输出）
如果为固定宽度的卸载指定 null 字符串，并且输出列的宽度小于 null 字符串的宽度，则将发生以下行为：  
+ 使用空字段作为非字符列的输出 
+ 针对字符列报告错误 
与用户定义的字符串表示 null 值的其他数据类型不同，Amazon Redshift 使用 JSON 格式导出 SUPER 数据列，并根据 JSON 格式将其表示为 null。因此，SUPER 数据列会忽略 UNLOAD 命令中使用的 NULL [AS] 选项。

ESCAPE   
对于分隔的卸载文件中的 CHAR 和 VARCHAR 列，将在每次出现的以下字符之前放置一个转义字符 (`\`)：  
+ 换行：`\n`
+ 回车：`\r`
+ 为卸载的数据指定的分隔符。
+ 转义字符：`\`
+ 引号字符：`"` 或 `'`（如果在 UNLOAD 命令中同时指定 ESCAPE 和 ADDQUOTES）。
如果已将 COPY 与 ESCAPE 选项结合使用来加载数据，则还必须在 UNLOAD 命令中指定 ESCAPE 选项以生成反向输出文件。同样，如果您使用 ESCAPE 选项执行 UNLOAD 命令，则在您对相同数据执行 COPY 操作时将需要使用 ESCAPE 选项。

ALLOWOVERWRITE   <a name="allowoverwrite"></a>
默认情况下，如果 UNLOAD 找到可能会覆盖的文件，则该命令将失败。如果指定 ALLOWOVERWRITE，则 UNLOAD 将覆盖现有文件（包括清单文件）。

CLEANPATH  <a name="cleanpath"></a>
CLEANPATH 选项会删除位于 TO 子句中指定的 Amazon S3 路径中的现有文件，然后再将文件卸载到指定位置。  
如果包含 PARTITION BY 子句，则只会从分区文件夹中删除现有文件，以接收 UNLOAD 操作生成的新文件。  
您必须拥有 Amazon S3 桶的 `s3:DeleteObject` 权限。有关更多信息，请参阅《Amazon Simple Storage Service 用户指南》**中的 Amazon S3 [中的策略和权限](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-policy-language-overview.html)。您使用 CLEANPATH 选项删除的文件将永久删除并且无法恢复。如果目标 Amazon S3 存储桶启用了版本控制，则带有 CLEANPATH 选项的 UNLOAD 不会移除文件的先前版本。  
如果您指定了 ALLOWOVERWRITE 选项，则无法指定 CLEANPATH 选项。

PARALLEL   <a name="unload-parallel"></a>
默认情况下，UNLOAD 根据集群中切片的数量将数据并行写入到多个文件。默认选项为 ON 或 TRUE。如果 PARALLEL 为 OFF 或 FALSE，UNLOAD 将按顺序写入到一个或多个数据文件，并完全根据 ORDER BY 子句（如果已使用）进行排序。数据文件的最大大小为 6.2 GB。例如，如果您卸载 13.4GB 数据，则 UNLOAD 将创建以下三个文件。  

```
s3://amzn-s3-demo-bucket/key000    6.2 GB
s3://amzn-s3-demo-bucket/key001    6.2 GB
s3://amzn-s3-demo-bucket/key002    1.0 GB
```
UNLOAD 命令旨在使用并行处理。对于大多数情况，特别是文件将用于通过 COPY 命令加载表时，我们建议保留 PARALLEL 为启用状态。

MAXFILESIZE [AS] 最大大小 [ MB \$1 GB ]   <a name="unload-maxfilesize"></a>
指定 UNLOAD 在 Amazon S3 中创建的文件的最大大小。可以指定 5 MB 到 6.2 GB 之间的十进制值。AS 关键字是可选的。默认单位为 MB。如果未指定 MAXFILESIZE，则默认最大文件大小为 6.2 GB。清单文件（如果使用）的大小不受 MAXFILESIZE 的影响。

ROWGROUPSIZE [AS] size [ MB \$1 GB ]   <a name="unload-rowgroupsize"></a>
指定行组的大小。选择更大的容量可以减少行组的数量，从而减少网络通信量。指定介于 32MB 到 128MB 之间的整数值。AS 关键字是可选的。默认单位为 MB。  
如果未指定 ROWGROUPSIZE，则默认大小为 32MB。要使用此参数，存储格式必须是 Parquet，节点类型必须是 ra3.4xlarge、ra3.16xlarge 或 dc2.8xlarge。

REGION [AS] '*aws-region*'  <a name="unload-region"></a>
指定目标 Amazon S3 桶所在的 AWS 区域。当 UNLOAD 的目标 Amazon S3 桶与 Amazon Redshift 数据库不在同一个 AWS 区域时，需要 REGION。  
*aws\$1region* 的值必须与《AWS 一般参考》**的 [Amazon Redshift 区域和端点](https://docs.aws.amazon.com/general/latest/gr/rande.html#redshift_region)中列出的 AWS 区域匹配。  
默认情况下，UNLOAD 假定目标 Amazon S3 桶位于 Amazon Redshift 数据库所在的 AWS 区域。

EXTENSION ‘*extension-name*'  <a name="unload-extension"></a>
指定要附加到卸载文件的名称后的文件扩展名。Amazon Redshift 不运行任何验证，因此您必须验证指定的文件扩展名是否正确。如果您指定压缩方法而不提供扩展名，则 Amazon Redshift 只会将压缩方法的扩展名添加到文件名。如果您不提供任何扩展名，也不指定压缩方法，则 Amazon Redshift 不会向文件名添加任何内容。

## 使用说明
<a name="unload-usage-notes"></a>

### 将 ESCAPE 用于所有分隔的文本 UNLOAD 操作
<a name="unload-usage-escape"></a>

在使用分隔符执行 UNLOAD 时，您的数据可能包含该分隔符或 ESCAPE 选项描述中列出的任意字符。在这种情况下，必须将 ESCAPE 选项与 UNLOAD 语句一起使用。如果不将 ESCAPE 选项与 UNLOAD 结合使用，则使用卸载的数据执行的后续 COPY 操作可能会失败。

**重要**  
我们强烈建议您始终将 ESCAPE 与 UNLOAD 和 COPY 语句一起使用。例外情况是您确定您的数据不包含任何分隔符或可能需要转义的其他字符。

### 丢失浮点精度
<a name="unload-usage-floating-point-precision"></a>

您可能遇到连续卸载并重新加载的浮点数据的精度丢失的情况。

### Limit 子句
<a name="unload-usage-limit-clause"></a>

SELECT 查询无法在外部 SELECT 中使用 LIMIT 子句。例如，以下 UNLOAD 语句将失败。

```
unload ('select * from venue limit 10')
to 's3://amzn-s3-demo-bucket/venue_pipe_' iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

应改用嵌套的 LIMIT 子句，如下例所示。

```
unload ('select * from venue where venueid in
(select venueid from venue order by venueid desc limit 10)')
to 's3://amzn-s3-demo-bucket/venue_pipe_' iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

您也可以使用 LIMIT 子句通过 SELECT…INTO 或 CREATE TABLE AS 来填充表，然后从该表卸载。

### 卸载 GEOMETRY 数据类型的列
<a name="unload-usage-geometry"></a>

您只能将 GEOMETRY 列卸载为文本或 CSV 格式。无法使用 `FIXEDWIDTH` 选项卸载 GEOMETRY 数据。以扩展的已知二进制 (EWKB) 格式的十六进制形式卸载数据。如果 EWKB 数据的大小大于 4 MB，则会出现警告，因为以后无法将数据加载到表中。

### 卸载 HLLSKETCH 数据类型
<a name="unload-usage-hll"></a>

您只能将 HLLSKETCH 列卸载为文本或 CSV 格式。无法使用 `FIXEDWIDTH` 选项卸载 HLLSKETCH 数据。对于密集的 HyperLogLog 草图，数据将以 Base64 格式卸载，对于稀疏 HyperLogLog 草图，则以 JSON 格式卸载数据。有关更多信息，请参阅 [HyperLogLog 函数](hyperloglog-functions.md)。

以下示例将包含 HLLSKETCH 列的表导出到文件中。

```
CREATE TABLE a_table(an_int INT, b_int INT);
INSERT INTO a_table VALUES (1,1), (2,1), (3,1), (4,1), (1,2), (2,2), (3,2), (4,2), (5,2), (6,2);

CREATE TABLE hll_table (sketch HLLSKETCH);
INSERT INTO hll_table select hll_create_sketch(an_int) from a_table group by b_int;

UNLOAD ('select * from hll_table') TO 's3://amzn-s3-demo-bucket/unload/'
IAM_ROLE 'arn:aws:iam::0123456789012:role/MyRedshiftRole' NULL AS 'null' ALLOWOVERWRITE CSV;
```

### 卸载 VARBYTE 数据类型的列
<a name="unload-usage-varbyte"></a>

您只能将 VARBYTE 列卸载为文本或 CSV 格式。以十六进制形式卸载数据。无法使用 `FIXEDWIDTH` 选项卸载 VARBYTE 数据。不支持 `ADDQUOTES` 选项“卸载到 CSV”。VARBYTE 列不得为 PARTITIONED BY 列。

### FORMAT AS PARQUET 子句
<a name="unload-parquet-usage"></a>

使用 FORMAT AS PARQUET 时，请注意以下注意事项：
+ 卸载到 Parquet 不使用文件级压缩。每个行组都使用 SNAPPY 进行压缩。
+ 如果未指定 MAXFILESIZE，则默认最大文件大小为 6.2 GB。您可以使用 MAXFILESIZE 指定 5 MB–6.2 GB 的文件大小。写入文件时，实际文件大小是近似值，因此它可能不完全等于您指定的数字。

  要最大限度地提高扫描性能，Amazon Redshift 尝试创建包含相同大小的 32 MB 行组的 Parquet 文件。您指定的 MAXFILESIZE 值会自动向下舍入为 32 MB 的最接近倍数。例如，如果您指定 MAXFILESIZE 200 MB，则卸载的每个 Parquet 文件大约为 192 MB（32 MB 行组 x 6 = 192 MB）。
+ 如果列使用 TIMESTAMPTZ 数据格式，则只卸载时间戳值。未卸载时区信息。
+ 不要指定以下划线 (\$1) 或句点 (.) 字符开头的文件名前缀。Redshift Spectrum 将以这些字符开头的文件视为隐藏文件并忽略它们。

### PARTITION BY 子句
<a name="unload-partitionby-usage"></a>

使用 PARTITION BY 时，请注意以下注意事项：
+ 分区列不包含在输出文件中。
+ 请确保在 UNLOAD 语句中使用的 SELECT 查询中包含分区列。您可以在 UNLOAD 命令中指定任意数量的分区列。但有一个限制，即至少应有一个非分区列作为文件的一部分。
+ 如果分区键值为 null，Amazon Redshift 会自动将该数据卸载到名为 `partition_column=__HIVE_DEFAULT_PARTITION__` 的默认分区中。
+ UNLOAD 命令不会对外部目录进行任何调用。要将新分区注册为现有外部表的一部分，请使用单独的 ALTER TABLE ... ADD PARTITION ... 命令。或者，您可以运行 CREATE EXTERNAL TABLE 命令将卸载的数据注册为新的外部表。也可以使用 AWS Glue 爬网程序填充您的 Data Catalog。有关更多信息，请参阅《AWS Glue 开发人员指南》**中的[定义爬网程序](https://docs.aws.amazon.com/glue/latest/dg/add-crawler.html)。
+ 如果使用 MANIFEST 选项，则 Amazon Redshift 在根 Amazon S3 文件夹中仅生成一个清单文件。
+ 可以用作分区键的列数据类型为：SMALLINT、INTEGER、BIGINT、DECIMAL、REAL、BOOLEAN、CHAR、VARCHAR、DATE 和 TIMESTAMP。

### 使用 ASSUMEROLE 权限授予对 UNLOAD 操作的 IAM 角色的访问权限
<a name="unload-assumerole-privilege-usage"></a>

要为特定用户和组提供对 UNLOAD 操作的 IAM 角色的访问权限，超级用户可以向用户和组授予 IAM 角色的 ASSUMEROLE 权限。有关信息，请参阅 [GRANT](r_GRANT.md)。

### UNLOAD 不支持 Amazon S3 接入点别名
<a name="unload-usage-s3-access-point-alias"></a>

不得将 Amazon S3 接入点别名与 UNLOAD 命令一起使用。

## 示例
<a name="r_UNLOAD-examples"></a>

有关如何使用 UNLOAD 命令的示例，请参阅 [UNLOAD 示例](r_UNLOAD_command_examples.md)。

# UNLOAD 示例
<a name="r_UNLOAD_command_examples"></a>

这些示例演示了 UNLOAD 命令的各种参数。许多示例使用 TICKIT 示例数据集。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

**注意**  
为便于阅读，这些示例包含换行符。请不要在您的 *credentials-args* 字符串中包含换行符或空格。

## 将 VENUE 卸载到竖线分隔的文件（默认分隔符）
<a name="unload-examples-venue"></a>

以下示例卸载 VENUE 表并将数据写入到 `s3://amzn-s3-demo-bucket/unload/`：

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/unload/'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

默认情况下，UNLOAD 为每个切片写入一个或多个文件。假定一个双节点集群中的每个节点有两个切片，上一个示例在 `amzn-s3-demo-bucket` 中会创建这些文件：

```
unload/0000_part_00
unload/0001_part_00
unload/0002_part_00
unload/0003_part_00
```

为了更好地区分输出文件，可在位置中包含前缀。以下示例卸载 VENUE 表并将数据写入到 `s3://amzn-s3-demo-bucket/unload/venue_pipe_`：

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/unload/venue_pipe_'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

最后在 `unload` 文件夹中生成四个文件，再次假定有四个切片。

```
venue_pipe_0000_part_00
venue_pipe_0001_part_00
venue_pipe_0002_part_00
venue_pipe_0003_part_00
```

## 将 LINEITEM 表卸载到分区的 Parquet 文件
<a name="unload-examples-partitioned-parquet"></a>

以下示例以 Parquet 格式卸载 LINEITEM 表，按 `l_shipdate` 列进行分区。

```
unload ('select * from lineitem')
to 's3://amzn-s3-demo-bucket/lineitem/'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
PARQUET
PARTITION BY (l_shipdate);
```

假设有四个切片，生成的 Parquet 文件会动态分区到不同文件夹中。

```
s3://amzn-s3-demo-bucket/lineitem/l_shipdate=1992-01-02/0000_part_00.parquet
                                             0001_part_00.parquet
                                             0002_part_00.parquet
                                             0003_part_00.parquet
s3://amzn-s3-demo-bucket/lineitem/l_shipdate=1992-01-03/0000_part_00.parquet
                                             0001_part_00.parquet
                                             0002_part_00.parquet
                                             0003_part_00.parquet
s3://amzn-s3-demo-bucket/lineitem/l_shipdate=1992-01-04/0000_part_00.parquet
                                             0001_part_00.parquet
                                             0002_part_00.parquet
                                             0003_part_00.parquet
...
```

**注意**  
在某些情况下，UNLOAD 命令使用的是 INCLUDE 选项，如以下 SQL 语句所示。  

```
unload ('select * from lineitem')
to 's3://amzn-s3-demo-bucket/lineitem/'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
PARQUET
PARTITION BY (l_shipdate) INCLUDE;
```
在这些情况下，`l_shipdate` 列也在 Parquet 文件中的数据中。否则，`l_shipdate` 列数据不在 Parquet 文件中。

## 将 VENUE 表卸载到 JSON 文件
<a name="unload-examples-json"></a>

以下示例卸载了 VENUE 表并将 JSON 格式的数据写入到 `s3://amzn-s3-demo-bucket/unload/`。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/unload/'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
JSON;
```

以下是 VENUE 表中的示例行。

```
venueid | venuename                  | venuecity       | venuestate | venueseats
--------+----------------------------+-----------------+------------+-----------
      1 | Pinewood Racetrack         | Akron           | OH         | 0
      2 | Columbus "Crew" Stadium    | Columbus        | OH         | 0
      4 | Community, Ballpark, Arena | Kansas City     | KS         | 0
```

卸载到 JSON 后，文件的格式类似于以下形式。

```
{"venueid":1,"venuename":"Pinewood Racetrack","venuecity":"Akron","venuestate":"OH","venueseats":0}
{"venueid":2,"venuename":"Columbus \"Crew\" Stadium ","venuecity":"Columbus","venuestate":"OH","venueseats":0}
{"venueid":4,"venuename":"Community, Ballpark, Arena","venuecity":"Kansas City","venuestate":"KS","venueseats":0}
```

## 将 VENUE 上传到 CSV 文件
<a name="unload-examples-csv"></a>

以下示例卸载 VENUE 表并将 CSV 格式的数据写入到 `s3://amzn-s3-demo-bucket/unload/`。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/unload/'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
CSV;
```

假设 VENUE 表包含以下行。

```
venueid | venuename                  | venuecity       | venuestate | venueseats
--------+----------------------------+-----------------+------------+-----------
      1 | Pinewood Racetrack         | Akron           | OH         | 0
      2 | Columbus "Crew" Stadium    | Columbus        | OH         | 0
      4 | Community, Ballpark, Arena | Kansas City     | KS         | 0
```

卸载文件类似于以下内容。

```
1,Pinewood Racetrack,Akron,OH,0
2,"Columbus ""Crew"" Stadium",Columbus,OH,0
4,"Community, Ballpark, Arena",Kansas City,KS,0
```

## 将 VENUE 卸载到使用分隔符的 CSV 文件
<a name="unload-examples-csv-delimiter"></a>

以下示例卸载 VENUE 表并使用竖线字符 (\$1) 作为分隔符以 CSV 格式写入数据。卸载的文件将写入到 `s3://amzn-s3-demo-bucket/unload/`。此示例中的 VENUE 表在第一行 (`Pinewood Race|track`) 的值中包含竖线字符。这样做是为了表明结果中的值已用双引号引起来。双引号由双引号进行转义，整个字段用双引号引起来。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/unload/'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
CSV DELIMITER AS '|';
```

假设 VENUE 表包含以下行。

```
venueid | venuename                  | venuecity       | venuestate | venueseats
--------+----------------------------+-----------------+------------+-------------
      1 | Pinewood Race|track        | Akron           | OH         | 0
      2 | Columbus "Crew" Stadium    | Columbus        | OH         | 0
      4 | Community, Ballpark, Arena | Kansas City     | KS         | 0
```

卸载文件类似于以下内容。

```
1|"Pinewood Race|track"|Akron|OH|0
2|"Columbus ""Crew"" Stadium"|Columbus|OH|0
4|Community, Ballpark, Arena|Kansas City|KS|0
```

## 使用清单文件卸载 VENUE
<a name="unload-examples-manifest"></a>

要创建清单文件，请包含 MANIFEST 选项。以下示例卸载 VENUE 表，并将清单文件与数据文件一起写入到 s3://amzn-s3-demo-bucket/venue\$1pipe\$1：

**重要**  
如果使用 MANIFEST 选项卸载文件，则应在加载文件时将 MANIFEST 选项与 COPY 命令结合使用。如果您使用相同的前缀来加载文件且不指定 MANIFEST 选项，则 COPY 将失败，因为它假定清单文件是数据文件。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/venue_pipe_' iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
manifest;
```

最后生成下面的 5 个文件：

```
s3://amzn-s3-demo-bucket/venue_pipe_0000_part_00
s3://amzn-s3-demo-bucket/venue_pipe_0001_part_00
s3://amzn-s3-demo-bucket/venue_pipe_0002_part_00
s3://amzn-s3-demo-bucket/venue_pipe_0003_part_00
s3://amzn-s3-demo-bucket/venue_pipe_manifest
```

下面显示了清单文件的内容。

```
{
  "entries": [
    {"url":"s3://amzn-s3-demo-bucket/tickit/venue_0000_part_00"},
    {"url":"s3://amzn-s3-demo-bucket/tickit/venue_0001_part_00"},
    {"url":"s3://amzn-s3-demo-bucket/tickit/venue_0002_part_00"},
    {"url":"s3://amzn-s3-demo-bucket/tickit/venue_0003_part_00"}
  ]
}
```

## 使用 MANIFEST VERBOSE 卸载 VENUE
<a name="unload-examples-manifest-verbose"></a>

指定 MANIFEST VERBOSE 选项时，清单文件包含以下部分：
+ `entries` 部分列出每个文件的 Amazon S3 路径、文件大小和行数。
+ `schema` 部分列出每列的列名、数据类型和维度。
+ `meta` 部分显示所有文件的总文件大小和行数。

以下示例使用 MANIFEST VERBOSE 选项卸载 VENUE 表。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/unload_venue_folder/'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
manifest verbose;
```

下面显示了清单文件的内容。

```
{
  "entries": [
    {"url":"s3://amzn-s3-demo-bucket/venue_pipe_0000_part_00", "meta": { "content_length": 32295, "record_count": 10 }},
    {"url":"s3://amzn-s3-demo-bucket/venue_pipe_0001_part_00", "meta": { "content_length": 32771, "record_count": 20 }},
    {"url":"s3://amzn-s3-demo-bucket/venue_pipe_0002_part_00", "meta": { "content_length": 32302, "record_count": 10 }},
    {"url":"s3://amzn-s3-demo-bucket/venue_pipe_0003_part_00", "meta": { "content_length": 31810, "record_count": 15 }}
  ],
  "schema": {
    "elements": [
      {"name": "venueid", "type": { "base": "integer" }},
      {"name": "venuename", "type": { "base": "character varying", 25 }},
      {"name": "venuecity", "type": { "base": "character varying", 25 }},
      {"name": "venuestate", "type": { "base": "character varying", 25 }},
      {"name": "venueseats", "type": { "base": "character varying", 25 }}
    ]
  },
  "meta": {
    "content_length": 129178,
    "record_count": 55
  },
  "author": {
    "name": "Amazon Redshift",
    "version": "1.0.0"
  }
}
```

## 使用标题卸载 VENUE
<a name="unload-examples-header"></a>

以下示例使用标题行卸载 VENUE。

```
unload ('select * from venue where venueseats > 75000')
to 's3://amzn-s3-demo-bucket/unload/'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
header
parallel off;
```

下面显示了带标题行的输出文件的内容。

```
venueid|venuename|venuecity|venuestate|venueseats
6|New York Giants Stadium|East Rutherford|NJ|80242
78|INVESCO Field|Denver|CO|76125
83|FedExField|Landover|MD|91704
79|Arrowhead Stadium|Kansas City|MO|79451
```

## 将 VENUE 卸载到较小的文件
<a name="unload-examples-maxfilesize"></a>

默认情况下，文件的最大大小为 6.2 GB。如果卸载数据大于 6.2GB，UNLOAD 将为每个 6.2GB 数据段创建一个新文件。要创建较小的文件，请包括 MAXFILESIZE 参数。假设上一个示例中的数据大小为 20 GB，则下面的 UNLOAD 命令将创建 20 个文件，每个文件的大小为 1 GB。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/unload/'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
maxfilesize 1 gb;
```

## 连续卸载 VENUE
<a name="unload-examples-serial"></a>

要连续卸载，请指定 PARALLEL OFF。然后，UNLOAD 将一次写入一个文件，每个文件的大小最多为 6.2 GB。

以下示例连续卸载 VENUE 表并将数据写入到 `s3://amzn-s3-demo-bucket/unload/`。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/unload/venue_serial_'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
parallel off;
```

最后生成一个名为 venue\$1serial\$1000 的文件。

如果卸载数据大于 6.2GB，UNLOAD 将为每个 6.2GB 数据段创建一个新文件。以下示例连续卸载 LINEORDER 表并将数据写入到 `s3://amzn-s3-demo-bucket/unload/`。

```
unload ('select * from lineorder')
to 's3://amzn-s3-demo-bucket/unload/lineorder_serial_'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
parallel off gzip;
```

最后生成下面的一系列文件。

```
lineorder_serial_0000.gz
lineorder_serial_0001.gz
lineorder_serial_0002.gz
lineorder_serial_0003.gz
```

为了更好地区分输出文件，可在位置中包含前缀。以下示例卸载 VENUE 表并将数据写入到 `s3://amzn-s3-demo-bucket/venue_pipe_`：

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/unload/venue_pipe_'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

最后在 `unload` 文件夹中生成四个文件，再次假定有四个切片。

```
venue_pipe_0000_part_00
venue_pipe_0001_part_00
venue_pipe_0002_part_00
venue_pipe_0003_part_00
```

## 从卸载文件中加载 VENUE
<a name="unload-examples-load"></a>

要从一组卸载文件加载表，只需使用 COPY 命令反向执行该过程即可。以下示例创建一个名为 LOADVENUE 的新表，并从上一个示例中创建的数据文件加载该表。

```
create table loadvenue (like venue);

copy loadvenue from 's3://amzn-s3-demo-bucket/venue_pipe_' iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

如果您使用 MANIFEST 选项通过卸载文件创建清单文件，则可使用相同的清单文件加载数据。您可以使用带有 MANIFEST 选项的 COPY 命令执行此操作。以下示例使用清单文件加载数据。

```
copy loadvenue
from 's3://amzn-s3-demo-bucket/venue_pipe_manifest' iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
manifest;
```

## 将 VENUE 卸载到加密文件
<a name="unload-examples-unload-encrypted"></a>

以下示例使用 AWS KMS 密钥将 VENUE 表卸载到一组加密文件。如果您使用 ENCRYPTED 选项来指定清单文件，清单文件也将加密。有关更多信息，请参阅 [卸载加密的数据文件](t_unloading_encrypted_files.md)。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/venue_encrypt_kms'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
kms_key_id '1234abcd-12ab-34cd-56ef-1234567890ab'
manifest
encrypted;
```

以下示例使用根对称密钥将 VENUE 表卸载到一组加密文件。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/venue_encrypt_cmk'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
master_symmetric_key 'EXAMPLEMASTERKEYtkbjk/OpCwtYSx/M4/t7DMCDIK722'
encrypted;
```

## 从加密文件中加载 VENUE
<a name="unload-examples-load-encrypted"></a>

要从使用带有 ENCRYPT 选项的 UNLOAD 创建的一组文件中加载表，请使用 COPY 命令逆向执行该过程。对于该命令，应使用 ENCRYPTED 选项并指定用于 UNLOAD 命令的相同根对称密钥。以下示例从上一个示例创建的加密数据文件中加载 LOADVENUE 表。

```
create table loadvenue (like venue);

copy loadvenue
from 's3://amzn-s3-demo-bucket/venue_encrypt_manifest'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
master_symmetric_key 'EXAMPLEMASTERKEYtkbjk/OpCwtYSx/M4/t7DMCDIK722'
manifest
encrypted;
```

## 将 VENUE 数据卸载到制表符分隔的文件
<a name="unload-examples-venue-tab"></a>

```
unload ('select venueid, venuename, venueseats from venue')
to 's3://amzn-s3-demo-bucket/venue_tab_'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
delimiter as '\t';
```

输出数据文件如下所示：

```
1	Toyota Park	Bridgeview	IL	0
2	Columbus Crew Stadium	Columbus	OH	0
3	RFK Stadium	Washington	DC	0
4	CommunityAmerica Ballpark	Kansas City	KS	0
5	Gillette Stadium	Foxborough	MA	68756
...
```

## 将 VENUE 卸载到固定宽度的数据文件
<a name="unload-venue-fixed-width"></a>

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/venue_fw_'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
fixedwidth as 'venueid:3,venuename:39,venuecity:16,venuestate:2,venueseats:6';
```

输出数据文件类似于以下内容。

```
1  Toyota Park              Bridgeview  IL0
2  Columbus Crew Stadium    Columbus    OH0
3  RFK Stadium              Washington  DC0
4  CommunityAmerica BallparkKansas City KS0
5  Gillette Stadium         Foxborough  MA68756
...
```

## 将 VENUE 卸载到一组制表符分隔的 GZIP 压缩文件
<a name="unload-examples-venue-gzip"></a>

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/venue_tab_'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
delimiter as '\t'
gzip;
```

## 将 VENUE 卸载到 GZIP 压缩文本文件
<a name="unload-examples-venue-extension-gzip"></a>

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/venue_tab_'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
extension 'txt.gz'
gzip;
```

## 卸载包含分隔符的数据
<a name="unload-examples-delimiter"></a>

此示例使用 ADDQUOTES 选项卸载逗号分隔的数据，其中一些实际数据字段中包含逗号。

首先，创建一个包含引号的表。

```
create table location (id int, location char(64));

insert into location values (1,'Phoenix, AZ'),(2,'San Diego, CA'),(3,'Chicago, IL');
```

然后，使用 ADDQUOTES 选项卸载数据。

```
unload ('select id, location from location')
to 's3://amzn-s3-demo-bucket/location_'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
delimiter ',' addquotes;
```

卸载的数据文件如下所示：

```
1,"Phoenix, AZ"
2,"San Diego, CA"
3,"Chicago, IL"
...
```

## 卸载联接查询的结果
<a name="unload-examples-join"></a>

以下示例卸载包含窗口函数的联接查询的结果。

```
unload ('select venuecity, venuestate, caldate, pricepaid,
sum(pricepaid) over(partition by venuecity, venuestate
order by caldate rows between 3 preceding and 3 following) as winsum
from sales join date on sales.dateid=date.dateid
join event on event.eventid=sales.eventid
join venue on event.venueid=venue.venueid
order by 1,2')
to 's3://amzn-s3-demo-bucket/tickit/winsum'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

输出文件如下所示：

```
Atlanta|GA|2008-01-04|363.00|1362.00
Atlanta|GA|2008-01-05|233.00|2030.00
Atlanta|GA|2008-01-06|310.00|3135.00
Atlanta|GA|2008-01-08|166.00|8338.00
Atlanta|GA|2008-01-11|268.00|7630.00
...
```

## 使用 NULL AS 进行卸载
<a name="unload-examples-null-as"></a>

默认情况下，UNLOAD 将 null 值作为空字符串输出。以下示例说明如何使用 NULL AS 来将文本字符串替换为 null 值。

对于这些示例，我们将向 VENUE 表添加几个 null 值。

```
update venue set venuestate = NULL
where venuecity = 'Cleveland';
```

从 VENUESTATE 为 null 的 VENUE 中选择，以验证列是否包含 NULL。

```
select * from venue where venuestate is null;

 venueid |        venuename         | venuecity | venuestate | venueseats
---------+--------------------------+-----------+------------+------------
      22 | Quicken Loans Arena      | Cleveland |            |          0
     101 | Progressive Field        | Cleveland |            |      43345
      72 | Cleveland Browns Stadium | Cleveland |            |      73200
```

现在，使用 NULL AS 选项对 VENUE 表执行 UNLOAD 以便将 null 值替换为字符串“`fred`”。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/nulls/'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
null as 'fred';
```

以下来自卸载文件的示例说明已将 null 值替换为 `fred`。这证明 VENUESEATS 的一些值也为 null，并且已替换为 `fred`。即使 VENUESEATS 的数据类型为整数，UNLOAD 也会将值转换为卸载文件中的文本，然后 COPY 会将其转换回整数。如果卸载到固定宽度的文件，则 NULL AS 字符串不得大于字段宽度。

```
248|Charles Playhouse|Boston|MA|0
251|Paris Hotel|Las Vegas|NV|fred
258|Tropicana Hotel|Las Vegas|NV|fred
300|Kennedy Center Opera House|Washington|DC|0
306|Lyric Opera House|Baltimore|MD|0
308|Metropolitan Opera|New York City|NY|0
  5|Gillette Stadium|Foxborough|MA|5
 22|Quicken Loans Arena|Cleveland|fred|0
101|Progressive Field|Cleveland|fred|43345
...
```

要从卸载文件加载表，请使用带相同 NULL AS 选项的 COPY 命令。

**注意**  
如果您尝试将 null 加载到定义为 NOT NULL 的列中，则 COPY 命令将失败。

```
create table loadvenuenulls (like venue);

copy loadvenuenulls from 's3://amzn-s3-demo-bucket/nulls/'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
null as 'fred';
```

要确认列包含 null 而不仅仅是包含空字符串，请从 LOADVENUENULLS 中选择并针对 null 进行筛选。

```
select * from loadvenuenulls where venuestate is null or venueseats is null;

 venueid |        venuename         | venuecity | venuestate | venueseats
---------+--------------------------+-----------+------------+------------
      72 | Cleveland Browns Stadium | Cleveland |            |      73200
     253 | Mirage Hotel             | Las Vegas | NV         |
     255 | Venetian Hotel           | Las Vegas | NV         |
      22 | Quicken Loans Arena      | Cleveland |            |          0
     101 | Progressive Field        | Cleveland |            |      43345
     251 | Paris Hotel              | Las Vegas | NV         |

...
```

您可以使用默认 NULL AS 行为对包含 null 的表执行 UNLOAD 操作，然后使用默认 NULL AS 行为对数据执行 COPY 以复制回表中；不过，目标表中的任何非数字字段将包含空字符串而不是 null。默认情况下，UNLOAD 将 null 转换为空字符串（空格或零长度）。对于数字列，COPY 会将空字符串转换为 NULL，但会将空字符串插入非数字列中。以下示例说明如何在执行 COPY 后使用默认 NULL AS 行为执行 UNLOAD。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/nulls/'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole' allowoverwrite;

truncate loadvenuenulls;
copy loadvenuenulls from 's3://amzn-s3-demo-bucket/nulls/'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

在本示例中，当您针对 null 进行筛选时，仅显示那些 VENUESEATS 包含 null 的行。其中，VENUESTATE 在表 (VENUE) 中包含 null，目标表 (LOADVENUENULLS) 中的 VENUESTATE 包含空字符串。

```
select * from loadvenuenulls where venuestate is null or venueseats is null;

 venueid |        venuename         | venuecity | venuestate | venueseats
---------+--------------------------+-----------+------------+------------
     253 | Mirage Hotel             | Las Vegas | NV         |
     255 | Venetian Hotel           | Las Vegas | NV         |
     251 | Paris Hotel              | Las Vegas | NV         |
...
```

要将空字符串作为 NULL 加载到非数字列，请包含 EMPTYASNULL 或 BLANKSASNULL 选项。可以同时使用这两个选项。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/nulls/'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole' allowoverwrite;

truncate loadvenuenulls;
copy loadvenuenulls from 's3://amzn-s3-demo-bucket/nulls/'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole' EMPTYASNULL;
```

要确认列包含 NULL，而不只是包含空格或空字符串，请从 LOADVENUENULLS 中选择并针对 null 进行筛选。

```
select * from loadvenuenulls where venuestate is null or venueseats is null;

 venueid |        venuename         | venuecity | venuestate | venueseats
---------+--------------------------+-----------+------------+------------
      72 | Cleveland Browns Stadium | Cleveland |            |      73200
     253 | Mirage Hotel             | Las Vegas | NV         |
     255 | Venetian Hotel           | Las Vegas | NV         |
      22 | Quicken Loans Arena      | Cleveland |            |          0
     101 | Progressive Field        | Cleveland |            |      43345
     251 | Paris Hotel              | Las Vegas | NV         |
     ...
```

## 使用 ALLOWOVERWRITE 参数卸载
<a name="unload-examples-allowoverwrite"></a>

默认情况下，UNLOAD 不会覆盖目标桶中的现有文件。例如，如果您运行同一个 UNLOAD 语句两次，而不修改目标桶中的文件，则第二次运行 UNLOAD 时将失败。要覆盖现有文件（包括清单文件），请指定 ALLOWOVERWRITE 选项。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/venue_pipe_'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
manifest allowoverwrite;
```

## 使用 PARALLEL 和 MANIFEST 参数卸载 EVENT 表
<a name="unload-examples-manifest-parallel"></a>

您可以并行卸载表并生成清单文件。Amazon S3 数据文件都是在同一级别创建的，且名称以模式 `0000_part_00` 为后缀。清单文件与数据文件位于同一文件夹级别，并以文本 `manifest` 为后缀。以下 SQL 卸载 EVENT 表并使用基本名称 `parallel` 创建文件

```
unload ('select * from mytickit1.event')
to 's3://amzn-s3-demo-bucket/parallel'
iam_role 'arn:aws:iam::123456789012:role/MyRedshiftRole'
parallel on
manifest;
```

Amazon S3 文件列表与以下内容类似。

```
 Name                       Last modified                        Size                  
 parallel0000_part_00	-   August 2, 2023, 14:54:39 (UTC-07:00) 52.1 KB  
 parallel0001_part_00	-   August 2, 2023, 14:54:39 (UTC-07:00) 53.4 KB
 parallel0002_part_00	-   August 2, 2023, 14:54:39 (UTC-07:00) 52.1 KB
 parallel0003_part_00	-   August 2, 2023, 14:54:39 (UTC-07:00) 51.1 KB
 parallel0004_part_00	-   August 2, 2023, 14:54:39 (UTC-07:00) 54.6 KB
 parallel0005_part_00	-   August 2, 2023, 14:54:39 (UTC-07:00) 53.4 KB
 parallel0006_part_00	-   August 2, 2023, 14:54:39 (UTC-07:00) 54.1 KB
 parallel0007_part_00	-   August 2, 2023, 14:54:39 (UTC-07:00) 55.9 KB
 parallelmanifest       -   August 2, 2023, 14:54:39 (UTC-07:00) 886.0 B
```

`parallelmanifest` 文件内容类似于以下内容。

```
{
  "entries": [
    {"url":"s3://amzn-s3-demo-bucket/parallel0000_part_00", "meta": { "content_length": 53316 }},
    {"url":"s3://amzn-s3-demo-bucket/parallel0001_part_00", "meta": { "content_length": 54704 }},
    {"url":"s3://amzn-s3-demo-bucket/parallel0002_part_00", "meta": { "content_length": 53326 }},
    {"url":"s3://amzn-s3-demo-bucket/parallel0003_part_00", "meta": { "content_length": 52356 }},
    {"url":"s3://amzn-s3-demo-bucket/parallel0004_part_00", "meta": { "content_length": 55933 }},
    {"url":"s3://amzn-s3-demo-bucket/parallel0005_part_00", "meta": { "content_length": 54648 }},
    {"url":"s3://amzn-s3-demo-bucket/parallel0006_part_00", "meta": { "content_length": 55436 }},
    {"url":"s3://amzn-s3-demo-bucket/parallel0007_part_00", "meta": { "content_length": 57272 }}
  ]
}
```

## 使用 PARALLEL OFF 和 MANIFEST 参数卸载 EVENT 表
<a name="unload-examples-manifest-serial"></a>

您可以串行卸载表（PARALLEL OFF）并生成清单文件。Amazon S3 数据文件都是在同一级别创建的，且名称以模式 `0000` 为后缀。清单文件与数据文件位于同一文件夹级别，并以文本 `manifest` 为后缀。

```
unload ('select * from mytickit1.event')
to 's3://amzn-s3-demo-bucket/serial'
iam_role 'arn:aws:iam::123456789012:role/MyRedshiftRole'
parallel off
manifest;
```

Amazon S3 文件列表与以下内容类似。

```
 Name                       Last modified                        Size                  
 serial0000             -   August 2, 2023, 15:54:39 (UTC-07:00) 426.7 KB  
 serialmanifest         -   August 2, 2023, 15:54:39 (UTC-07:00) 120.0 B
```

`serialmanifest` 文件内容类似于以下内容。

```
{
  "entries": [
    {"url":"s3://amzn-s3-demo-bucket/serial000", "meta": { "content_length": 436991 }}
  ]
}
```

## 使用 PARTITION BY 和 MANIFEST 参数卸载 EVENT 表
<a name="unload-examples-manifest-partition"></a>

您可以按分区卸载表并生成清单文件。在 Amazon S3 中创建了一个包含子分区文件夹的新文件夹，子文件夹中的数据文件的名称模式类似于 `0000_par_00`。清单文件与子文件夹位于同一文件夹级别，其名称为 `manifest`。

```
unload ('select * from mytickit1.event')
to 's3://amzn-s3-demo-bucket/partition'
iam_role 'arn:aws:iam::123456789012:role/MyRedshiftRole'
partition by (eventname)
manifest;
```

Amazon S3 文件列表与以下内容类似。

```
 Name                   Type     Last modified                        Size                  
 partition           	Folder
```

在 `partition` 文件夹中是具有分区名称的子文件夹和清单文件。下面显示的是 `partition` 文件夹中文件夹列表的底部，类似于下面的内容。

```
 Name                   Type      Last modified                        Size                  
 ...
 eventname=Zucchero/    Folder 
 eventname=Zumanity/    Folder 
 eventname=ZZ Top/      Folder  
 manifest          	    -	    August 2, 2023, 15:54:39 (UTC-07:00) 467.6 KB
```

在 `eventname=Zucchero/` 文件夹中是类似于以下内容的数据文件。

```
 Name               Last modified                        Size                  
 0000_part_00	-   August 2, 2023, 15:59:19 (UTC-07:00) 70.0 B
 0001_part_00	-   August 2, 2023, 15:59:16 (UTC-07:00) 106.0 B
 0002_part_00	-   August 2, 2023, 15:59:15 (UTC-07:00) 70.0 B
 0004_part_00	-   August 2, 2023, 15:59:17 (UTC-07:00) 141.0 B
 0006_part_00	-   August 2, 2023, 15:59:16 (UTC-07:00) 35.0 B
 0007_part_00	-   August 2, 2023, 15:59:19 (UTC-07:00) 108.0 B
```

`manifest` 文件内容的底部类似于以下内容。

```
{
  "entries": [
    ...
    {"url":"s3://amzn-s3-demo-bucket/partition/eventname=Zucchero/007_part_00", "meta": { "content_length": 108 }},
    {"url":"s3://amzn-s3-demo-bucket/partition/eventname=Zumanity/007_part_00", "meta": { "content_length": 72 }}
  ]
}
```

## 使用 MAXFILESIZE、ROWGROUPSIZE 和 MANIFEST 参数卸载 EVENT 表
<a name="unload-examples-manifest-maxsize"></a>

您可以并行卸载表并生成清单文件。Amazon S3 数据文件都是在同一级别创建的，且名称以模式 `0000_part_00` 为后缀。生成的 Parquet 数据文件限制为 256MB，行组大小限制为 128MB。清单文件与数据文件位于同一文件夹级别，并以 `manifest` 为后缀。

```
unload ('select * from mytickit1.event')
to 's3://amzn-s3-demo-bucket/eventsize'
iam_role 'arn:aws:iam::123456789012:role/MyRedshiftRole'
maxfilesize 256 MB
rowgroupsize 128 MB
parallel on
parquet
manifest;
```

Amazon S3 文件列表与以下内容类似。

```
 Name                            Type      Last modified                        Size 
 eventsize0000_part_00.parquet	parquet	August 2, 2023, 17:35:21 (UTC-07:00) 24.5 KB
 eventsize0001_part_00.parquet	parquet	August 2, 2023, 17:35:21 (UTC-07:00) 24.8 KB
 eventsize0002_part_00.parquet	parquet	August 2, 2023, 17:35:21 (UTC-07:00) 24.4 KB
 eventsize0003_part_00.parquet	parquet	August 2, 2023, 17:35:21 (UTC-07:00) 24.0 KB
 eventsize0004_part_00.parquet	parquet	August 2, 2023, 17:35:21 (UTC-07:00) 25.3 KB
 eventsize0005_part_00.parquet	parquet	August 2, 2023, 17:35:21 (UTC-07:00) 24.8 KB
 eventsize0006_part_00.parquet	parquet	August 2, 2023, 17:35:21 (UTC-07:00) 25.0 KB
 eventsize0007_part_00.parquet	parquet	August 2, 2023, 17:35:21 (UTC-07:00) 25.6 KB
 eventsizemanifest                 -       August 2, 2023, 17:35:21 (UTC-07:00) 958.0 B
```

`eventsizemanifest` 文件内容类似于以下内容。

```
{
  "entries": [
    {"url":"s3://amzn-s3-demo-bucket/eventsize0000_part_00.parquet", "meta": { "content_length": 25130 }},
    {"url":"s3://amzn-s3-demo-bucket/eventsize0001_part_00.parquet", "meta": { "content_length": 25428 }},
    {"url":"s3://amzn-s3-demo-bucket/eventsize0002_part_00.parquet", "meta": { "content_length": 25025 }},
    {"url":"s3://amzn-s3-demo-bucket/eventsize0003_part_00.parquet", "meta": { "content_length": 24554 }},
    {"url":"s3://amzn-s3-demo-bucket/eventsize0004_part_00.parquet", "meta": { "content_length": 25918 }},
    {"url":"s3://amzn-s3-demo-bucket/eventsize0005_part_00.parquet", "meta": { "content_length": 25362 }},
    {"url":"s3://amzn-s3-demo-bucket/eventsize0006_part_00.parquet", "meta": { "content_length": 25647 }},
    {"url":"s3://amzn-s3-demo-bucket/eventsize0007_part_00.parquet", "meta": { "content_length": 26256 }}
  ]
}
```

# UPDATE
<a name="r_UPDATE"></a>

**Topics**
+ [语法](#r_UPDATE-synopsis)
+ [参数](#r_UPDATE-parameters)
+ [使用说明](#r_UPDATE_usage_notes)
+ [UPDATE 语句的示例](c_Examples_of_UPDATE_statements.md)

如果满足条件，则更新一个或多个表列中的值。

**注意**  
单个 SQL 语句的最大大小为 16MB。

## 语法
<a name="r_UPDATE-synopsis"></a>

```
[ WITH [RECURSIVE] common_table_expression [, common_table_expression , ...] ]
            UPDATE table_name [ [ AS ] alias ] SET column = { expression | DEFAULT } [,...]

[ FROM fromlist ]
[ WHERE condition ]
```

## 参数
<a name="r_UPDATE-parameters"></a>

WITH 子句  
可选子句，指定一个或多个 *common-table-expressions*。请参阅 [WITH 子句](r_WITH_clause.md)。

 *table\$1name*   
一个临时或永久表。只有表所有者或对表具有 UPDATE 权限的用户可以更新行。如果您使用 FROM 子句或从表达式或条件中的表进行选择，则必须对这些表具有 SELECT 权限。您不能在此处为表提供别名；不过可以在 FROM 子句中指定别名。  
Amazon Redshift Spectrum 外部表为只读。您无法对外部表进行 UPDATE。

alias  
目标表的临时备用名称。别名是可选的。AS 关键字始终是可选的。

SET *column* =   
要修改的一个或多个列。未列出的列将保留其当前值。不要将表名包含在目标列的规范中。例如，`UPDATE tab SET tab.col = 1` 是无效的。

 *expression*   
一个定义指定列的新值的表达式。

DEFAULT   
使用 CREATE TABLE 语句中分配给列的默认值更新列。

FROM *tablelist*   
您可以通过引用其他表中的信息来更新表。在 FROM 子句中列出其他表，或者将子查询用作 WHERE 条件的一部分。FROM 子句中列出的表可以具有别名。如果您需要在列表中包含 UPDATE 语句的目标表，请使用别名。

WHERE *condition*   
一个可选子句，用于限制对符合条件的行的更新。当条件返回 `true` 时，将更新指定的 SET 列。条件可以是列上的简单谓词，也可以是基于子查询的结果的条件。  
可以在子查询中命名任何表，包括 UPDATE 的目标表。

## 使用说明
<a name="r_UPDATE_usage_notes"></a>

在更新表中的大量行后：
+ 对表执行 Vacuum 操作，以回收存储空间并对行重新排序。
+ 分析表以更新查询计划程序的统计数据。

UPDATE 语句的 FROM 子句中不支持左、右和完整外部联接；它们将返回以下错误：

```
ERROR: Target table must be part of an equijoin predicate
```

 如果需要指定外部联接，请在 UPDATE 语句的 WHERE 子句中使用子查询。

如果您的 UPDATE 语句需要自联接到目标表，您需要指定联接条件以及限定更新操作的行的 WHERE 子句条件。通常，在将目标表联接到自身或其他表时，最佳实践是使用可明确地将联接条件与限定要更新的行的条件分隔的子查询。

每行具有多个匹配项的 UPDATE 查询会在配置参数 `error_on_nondeterministic_update` 被设置为 *true* 时引发错误。有关更多信息，请参阅 [error\$1on\$1nondeterministic\$1update](r_error_on_nondeterministic_update.md)。

您可以更新 GENERATED BY DEFAULT AS IDENTITY 列。您可以使用您提供的值来更新定义为 GENERATED BY DEFAULT AS IDENTITY 的列。有关更多信息，请参阅 [GENERATED BY DEFAULT AS IDENTITY](r_CREATE_TABLE_NEW.md#identity-generated-bydefault-clause)。

# UPDATE 语句的示例
<a name="c_Examples_of_UPDATE_statements"></a>

有关以下示例中使用的表的更多信息，请参阅[示例数据库](c_sampledb.md)。

TICKIT 数据库中的 CATEGORY 表包含以下行：

```
+-------+----------+-----------+--------------------------------------------+
| catid | catgroup |  catname  |                  catdesc                   |
+-------+----------+-----------+--------------------------------------------+
| 5     | Sports   | MLS       | Major League Soccer                        |
| 11    | Concerts | Classical | All symphony, concerto, and choir concerts |
| 1     | Sports   | MLB       | Major League Baseball                      |
| 6     | Shows    | Musicals  | Musical theatre                            |
| 3     | Sports   | NFL       | National Football League                   |
| 8     | Shows    | Opera     | All opera and light opera                  |
| 2     | Sports   | NHL       | National Hockey League                     |
| 9     | Concerts | Pop       | All rock and pop music concerts            |
| 4     | Sports   | NBA       | National Basketball Association            |
| 7     | Shows    | Plays     | All non-musical theatre                    |
| 10    | Concerts | Jazz      | All jazz singers and bands                 |
+-------+----------+-----------+--------------------------------------------+
```

 **根据一系列值更新表** 

基于 CATID 列中的一系列值更新 CATGROUP 列。

```
UPDATE category
SET catgroup='Theatre'
WHERE catid BETWEEN 6 AND 8;

SELECT * FROM category
WHERE catid BETWEEN 6 AND 8;

+-------+----------+----------+---------------------------+
| catid | catgroup | catname  |          catdesc          |
+-------+----------+----------+---------------------------+
| 6     | Theatre  | Musicals | Musical theatre           |
| 7     | Theatre  | Plays    | All non-musical theatre   |
| 8     | Theatre  | Opera    | All opera and light opera |
+-------+----------+----------+---------------------------+
```

 **根据当前值更新表** 

基于 CATNAME 和 CATDESC 列的当前 CATGROUP 值更新这两个列：

```
UPDATE category
SET catdesc=default, catname='Shows'
WHERE catgroup='Theatre';

SELECT * FROM category
WHERE catname='Shows';

+-------+----------+---------+---------+
| catid | catgroup | catname | catdesc |
+-------+----------+---------+---------+
| 6     | Theatre  | Shows   | NULL    |
| 7     | Theatre  | Shows   | NULL    |
| 8     | Theatre  | Shows   | NULL    |
+-------+----------+---------+---------+)
```

在本示例中，CATDESC 列已设置为 null，因为创建表时未定义默认值。

运行以下命令可将 CATEGORY 表数据设置回原始值：

```
TRUNCATE category;

COPY category
FROM 's3://redshift-downloads/tickit/category_pipe.txt' 
DELIMITER '|' 
IGNOREHEADER 1 
REGION 'us-east-1'
IAM_ROLE default;
```

 **根据 WHERE 子句子查询结果更新表** 

基于 WHERE 子句中子查询的结果更新 CATEGORY 表：

```
UPDATE category
SET catdesc='Broadway Musical'
WHERE category.catid IN
(SELECT category.catid FROM category
JOIN event ON category.catid = event.catid
JOIN venue ON venue.venueid = event.venueid
JOIN sales ON sales.eventid = event.eventid
WHERE venuecity='New York City' AND catname='Musicals');
```

查看更新后的表：

```
SELECT * FROM category ORDER BY catid;

+-------+----------+-----------+--------------------------------------------+
| catid | catgroup |  catname  |                  catdesc                   |
+-------+----------+-----------+--------------------------------------------+
| 2     | Sports   | NHL       | National Hockey League                     |
| 3     | Sports   | NFL       | National Football League                   |
| 4     | Sports   | NBA       | National Basketball Association            |
| 5     | Sports   | MLS       | Major League Soccer                        |
| 6     | Shows    | Musicals  | Broadway Musical                           |
| 7     | Shows    | Plays     | All non-musical theatre                    |
| 8     | Shows    | Opera     | All opera and light opera                  |
| 9     | Concerts | Pop       | All rock and pop music concerts            |
| 10    | Concerts | Jazz      | All jazz singers and bands                 |
| 11    | Concerts | Classical | All symphony, concerto, and choir concerts |
+-------+----------+-----------+--------------------------------------------+
```

 **根据 WITH 子句子查询结果更新表** 

要使用 WITH 子句根据子查询的结果更新 CATEGORY 表，请使用以下示例。

```
WITH u1 as (SELECT catid FROM event ORDER BY catid DESC LIMIT 1) 
UPDATE category SET catid='200' FROM u1 WHERE u1.catid=category.catid;

SELECT * FROM category ORDER BY catid DESC LIMIT 1;

+-------+----------+---------+---------------------------------+
| catid | catgroup | catname |             catdesc             |
+-------+----------+---------+---------------------------------+
| 200   | Concerts | Pop     | All rock and pop music concerts |
+-------+----------+---------+---------------------------------+
```

## 根据联接条件结果更新表
<a name="c_Examples_of_UPDATE_statements-updating-a-table-based-on-the-result-of-a-join-condition"></a>

基于 EVENT 表中匹配的 CATID 行更新 CATEGORY 表中的原始 11 个行：

```
UPDATE category SET catid=100
FROM event
WHERE event.catid=category.catid;

SELECT * FROM category ORDER BY catid;

+-------+----------+-----------+--------------------------------------------+
| catid | catgroup |  catname  |                  catdesc                   |
+-------+----------+-----------+--------------------------------------------+
| 2     | Sports   | NHL       | National Hockey League                     |
| 3     | Sports   | NFL       | National Football League                   |
| 4     | Sports   | NBA       | National Basketball Association            |
| 5     | Sports   | MLS       | Major League Soccer                        |
| 10    | Concerts | Jazz      | All jazz singers and bands                 |
| 11    | Concerts | Classical | All symphony, concerto, and choir concerts |
| 100   | Concerts | Pop       | All rock and pop music concerts            |
| 100   | Shows    | Plays     | All non-musical theatre                    |
| 100   | Shows    | Opera     | All opera and light opera                  |
| 100   | Shows    | Musicals  | Broadway Musical                           |
+-------+----------+-----------+--------------------------------------------+
```

 请注意，在 FROM 子句中列出 EVENT 表，并且在 WHERE 子句中定义目标表的联接条件。只有 4 行符合更新条件。对于这 4 行，其原始 CATID 值为 6、7、8 和 9；EVENT 表中仅呈现这 4 个类别：

```
SELECT DISTINCT catid FROM event;

+-------+
| catid |
+-------+
| 6     |
| 7     |
| 8     |
| 9     |
+-------+
```

通过扩展上一个示例并向 WHERE 子句添加其他条件来更新 CATEGORY 表中的原始 11 个行。由于 CATGROUP 列的限制，只有一行符合更新条件（虽然这 4 行都符合联接条件）。

```
UPDATE category SET catid=100
FROM event
WHERE event.catid=category.catid
AND catgroup='Concerts';

SELECT * FROM category WHERE catid=100;

+-------+----------+---------+---------------------------------+
| catid | catgroup | catname |             catdesc             |
+-------+----------+---------+---------------------------------+
| 100   | Concerts | Pop     | All rock and pop music concerts |
+-------+----------+---------+---------------------------------+
```

编写此示例的另一种方法如下：

```
UPDATE category SET catid=100
FROM event JOIN category cat ON event.catid=cat.catid
WHERE cat.catgroup='Concerts';
```

这种方法的好处是，明确地将联接条件与限定要更新的行的任何其他条件分隔开。请注意，在 FROM 子句中使用了 CATEGORY 表的别名 CAT。

## 在 FROM 子句中使用外部联接进行更新
<a name="c_Examples_of_UPDATE_statements-updates-with-outer-joins-in-the-from-clause"></a>

上一个示例显示了 UPDATE 语句的 FROM 子句中指定的内部联接。以下示例返回一个错误，因为 FROM 子句不支持与目标表的外部联接：

```
UPDATE category SET catid=100
FROM event LEFT JOIN category cat ON event.catid=cat.catid
WHERE cat.catgroup='Concerts';
ERROR:  Target table must be part of an equijoin predicate
```

如果 UPDATE 语句需要外部联接，您可以将外部联接语法移到子查询中：

```
UPDATE category SET catid=100
FROM
(SELECT event.catid FROM event LEFT JOIN category cat ON event.catid=cat.catid) eventcat
WHERE category.catid=eventcat.catid
AND catgroup='Concerts';
```

## 在 SET 子句中使用另一个表中的列进行更新
<a name="c_Examples_of_UPDATE_statements-set-with-column-from-another-table"></a>

要使用 sales 表中的值更新 TICKIT 示例数据库中的 listing 表，请使用以下示例。

```
SELECT listid, numtickets FROM listing WHERE sellerid = 1 ORDER BY 1 ASC LIMIT 5;

+--------+------------+
| listid | numtickets |
+--------+------------+
| 100423 | 4          |
| 108334 | 24         |
| 117150 | 4          |
| 135915 | 20         |
| 205927 | 6          |
+--------+------------+

UPDATE listing
SET numtickets = sales.sellerid
FROM sales
WHERE sales.sellerid = 1 AND listing.sellerid = sales.sellerid;

SELECT listid, numtickets FROM listing WHERE sellerid = 1 ORDER BY 1 ASC LIMIT 5;

+--------+------------+
| listid | numtickets |
+--------+------------+
| 100423 | 1          |
| 108334 | 1          |
| 117150 | 1          |
| 135915 | 1          |
| 205927 | 1          |
+--------+------------+
```

# USE
<a name="r_USE_command"></a>

更改对其运行查询的数据库。SHOW USE 指向最近与 USE 命令一起使用的数据库。RESET USE 会重置所使用的数据库。这意味着，如果未在 SQL 中指定数据库，则将在当前数据库中搜索对象。

## 语法
<a name="r_USE-synopsis"></a>

```
USE database
```

## 示例
<a name="r_USE_command-examples"></a>

假设有三个数据库：`dev`、`pdb` 和 `pdb2`。假设每个数据库的公有架构中有两个表 `t`。首先，将数据插入不同数据库的表中：

```
dev=# insert into dev.public.t values (1);
INSERT 0 1
dev=# insert into pdb.public.t values (2);
INSERT 0 1
```

在未显式设置数据库的情况下，系统将使用已连接的数据库。检查当前数据库上下文：

```
dev=# show use;
Use Database

(1 row)
dev=> show search_path;
search_path
$user, public
(1 row)
```

在不指定数据库的情况下查询表 `t` 时，系统将使用当前数据库中的表：

```
dev=# select * from t;
c
----
1
(1 row)
```

使用 `use` 命令可在不更改连接的情况下切换数据库：

```
dev=# use pdb;
USE
dev=# show use;
 Use Database
--------------
 pdb
(1 row)
dev=# select * from t;
id
----
2
(1 row)
```

还可以显式指定架构：

```
dev=# select * from public.t;
id
----
2
(1 row)
```

现在，您可以在当前数据库中使用不同的架构创建表：

```
dev=# create table s1.t(id int);
CREATE TABLE
dev=# insert into pdb.s1.t values (3);
INSERT 0 1
```

当您未指定架构时，搜索路径决定了可以访问哪个架构的对象：

```
dev=# set search_path to public, s1;
SET
dev=# select * from t;
 id
----
  2
(1 row)
```

更改架构的顺序以访问不同的表：

```
dev=# set search_path to s1, public;
SET
dev=# show search_path;
 search_path
-------------
 s1, public
(1 row)
dev=# select * from t;
 id
----
  3
(1 row)
```

在保持原始连接的同时切换到另一个数据库：

```
dev=# show use;
 Use Database
--------------
 pdb
(1 row)
dev=# use pdb2;
USE
dev=# show use;
 Use Database
--------------
 pdb2
(1 row)
```

切换数据库时，搜索路径会重置为默认值：

```
dev=# show search_path;
  search_path
---------------
 $user, public
(1 row)
```

在当前数据库中创建表并插入数据：

```
dev=# create table pdb2.public.t(id int);
CREATE TABLE
dev=# insert into pdb2.public.t values (4);
INSERT 0 1
dev=# select * from t;
 id
----
  4
(1 row)
```

在事务中，您可以使用由三部分组成的表示法来写入当前数据库并从任何数据库读取。这还包括连接的数据库：

```
dev=# show use;
 Use Database
--------------
 pdb2
(1 row)

dev=# BEGIN;
BEGIN
dev=# select * from t;
 id
----
  4
(1 row)

dev=# insert into t values (5);
INSERT 0 1
dev=# select * from t;
 id
----
  4
  5
(2 rows)

dev=# select * from pdb.public.t;
 id
----
  2
(1 row)

dev=# select * from dev.public.t;
 id
----
  1
(1 row)
```

重置为连接的数据库。请注意，这不仅会恢复到以前使用的数据库 `pdb`，还会重置为连接的数据库。搜索路径也会更改为默认路径：

```
dev=# RESET USE;
RESET
dev=# select * from t;
c
----
1
(1 row)
dev=# show use;
 Use Database
--------------

(1 row)

dev=# show search_path;
  search_path
---------------
 $user, public
(1 row)
```

您可以在事务开始时更改数据库，但不能在运行查询之后更改数据库：

```
dev=# BEGIN;
BEGIN
dev=# use pdb;
USE
dev=# use pdb2;
USE
dev=# use pdb;
USE
dev=# select * from t;
 id
----
  2
(1 row)
dev=# use pdb2;
ERROR:  USEd Database cannot be set or reset inside a transaction after another command.
dev=# rollback;
ROLLBACK
(1 row)
```

### 数据目录示例
<a name="use-redlake-example"></a>

首先，在不同的架构和目录中创建表以演示跨目录查询。首先在连接的数据库中创建表。

```
dev=# CREATE TABLE dev.public.t (col INT);
dev=# INSERT INTO dev.public.t VALUES (1);
dev=# CREATE SCHEMA write_schema;
dev=# CREATE TABLE dev.write_schema.t (state char (2));
dev=# INSERT INTO dev.write_schema.t VALUES ('WA');
```

现在，在不同的目录中创建类似的表。这演示了如何使用跨目录数据库。

```
dev=# CREATE TABLE my_db@my_catalog.public.t (col INT);
dev=# INSERT INTO my_db@my_catalog.public.t VALUES (100);
dev=# CREATE SCHEMA my_db@my_catalog.write_schema;
dev=# CREATE TABLE my_db@my_catalog.write_schema.t (state char (2));
dev=# INSERT INTO my_db@my_catalog.write_schema.t VALUES ('CA');
```

检查当前数据库上下文。在未显式设置数据库的情况下，系统将使用连接的数据库。

```
dev=# SHOW USE;
 Use Database
--------------

(1 row)

dev=# SHOW search_path;
  search_path
---------------
 $user, public
(1 row)

dev=# SELECT * FROM t;
 col
-----
   1
(1 row)
```

将 USEd 数据库设置为查询其它目录中的表。

```
dev=# USE my_db@my_catalog;

dev=# SHOW USE;
            Use Database
-------------------------------------
 my_db@my_catalog
(1 row)

dev=# SHOW search_path;
  search_path
---------------
 $user, public
(1 row)
```

查询表 t 时，结果来自跨目录数据库。

```
dev=# SELECT * FROM t;
 col
-----
 100
(1 row)

dev=# SELECT * FROM public.t;
 col
-----
 100
(1 row)

dev=# SELECT * FROM my_db@my_catalog.public.t;
 col
-----
 100
(1 row)
```

更改搜索路径以访问 USEd 数据库内不同架构中的表。

```
dev=# SET search_path to write_schema;

dev=# SHOW search_path;
 search_path
--------------
 write_schema
(1 row)

dev=# SELECT * FROM t;
 state
-------
 CA
(1 row)

dev=# SELECT * FROM write_schema.t;
 state
-------
 CA
(1 row)

dev=# SELECT * FROM my_db@my_catalog.write_schema.t;
 state
-------
 CA
(1 row)
```

即使 USE 设置为跨目录数据库，也仍然可以显式查询原始数据库。

```
dev=# SELECT * FROM dev.write_schema.t;
 state
-------
 WA
(1 row)
```

重置 USEd 数据库以再次引用所连接数据库中的对象。

```
dev=# RESET USE;

dev=# SHOW USE;
 Use Database
--------------

(1 row)
```

请注意，重置 USE 时，search\$1path 会重置。

```
dev=# SHOW search_path;
  search_path
---------------
 $user, public
(1 row)
```

重置后，查询现在引用原始连接的数据库。

```
dev=# SELECT * FROM t;
 col
-----
   1
(1 row)

dev=# SELECT * FROM public.t;
 col
-----
   1
(1 row)

dev=# SELECT * FROM dev.public.t;
 col
-----
   1
(1 row)
```

可以修改原始数据库中的搜索路径以访问不同的架构。

```
dev=# SET search_path to write_schema;

dev=# SHOW search_path;
 search_path
--------------
 write_schema
(1 row)

dev=# SELECT * FROM t;
 state
-------
 WA
(1 row)

dev=# SELECT * FROM write_schema.t;
 state
-------
 WA
(1 row)

dev=# SELECT * FROM dev.write_schema.t;
 state
-------
 WA
(1 row)
```

# VACUUM
<a name="r_VACUUM_command"></a>

对行重新排序，并回收指定表或当前数据库中所有表的空间。

**注意**  
只有拥有必要的表权限的用户才能有效地对表执行 vacuum 操作。如果在没有必需的表权限的情况下运行 VACUUM 操作，该操作将成功完成，但不起任何作用。有关能有效运行 VACUUM 操作的有效表权限列表，请参阅以下“必需权限”部分。

Amazon Redshift 自动对数据进行排序，并在后台运行 VACUUM DELETE。这减少了运行 VACUUM 命令的需要。有关更多信息，请参阅 [对表执行 vacuum 操作](t_Reclaiming_storage_space202.md)。

默认情况下，当任意表中有 95% 的行已有序时，VACUUM 会为该表跳过排序阶段。跳过排序阶段能够显著提高 VACUUM 的性能。要更改某个表的默认排序或删除阈值，请在运行 VACUUM 时包含表名称和 TO *threshold* PERCENT 参数。

在对表执行 vacuum 操作时，用户可以访问表。您可以在对表执行 vacuum 操作的同时执行查询和写入操作，但如果数据操作语言 (DML) 命令和 vacuum 操作同时运行，则二者可能花费更长时间。如果您在 vacuum 操作期间执行 UPDATE 和 DELETE 语句，则系统性能可能会降低。VACUUM DELETE 会临时阻止更新和删除操作。

Amazon Redshift 在后台自动执行 DELETE ONLY vacuum 操作。当用户运行数据定义语言 (DDL) 操作（如 ALTER TABLE）时，自动 vacuum 操作将暂停。

**注意**  
Amazon Redshift VACUUM 命令语法和行为与 PostgreSQL VACUUM 操作的语法和行为大不相同。例如，Amazon Redshift 中的默认 VACUUM 操作是 VACUUM FULL，该操作可回收磁盘空间并对所有行进行重新排序。相比之下，PostgreSQL 中的默认 VACUUM 操作只能回收空间并使其可供重复使用。

有关更多信息，请参阅 [对表执行 vacuum 操作](t_Reclaiming_storage_space202.md)。

## 所需的权限
<a name="r_VACUUM_command-privileges"></a>

以下是 VACUUM 所需的权限：
+ Superuser
+ 具有 VACUUM 权限的用户
+ 表拥有者
+ 向其共享表的数据库拥有者

## 语法
<a name="r_VACUUM_command-synopsis"></a>

```
VACUUM [ FULL | SORT ONLY | DELETE ONLY | REINDEX | RECLUSTER ]
[ [ table_name ] [ TO threshold PERCENT ] [ BOOST ] ]
```

## 参数
<a name="r_VACUUM_command-parameters"></a>

FULL   <a name="vacuum-full"></a>
对指定的表（或当前数据库中的所有表）进行排序，并回收由前面的 UPDATE 和 DELETE 操作标记为删除的行所占用的磁盘空间。VACUUM FULL 是默认值。  
完全 vacuum 操作不会为交错的表重建索引。要在执行完全 vacuum 操作后对交错的表重建索引，请使用 [VACUUM REINDEX](#vacuum-reindex) 选项。  
如果任意表已至少 95% 有序，则默认情况下 VACUUM FULL 会为其跳过排序阶段。如果 VACUUM 能够跳过排序阶段，它将执行 DELETE ONLY 并在删除阶段回收空间，这样，至少有 95% 的剩余行不会被标记为删除。   
如果未达到排序阈值（例如，如果对 90% 的行进行了排序）且 VACUUM 执行了完全排序，则 VACUUM 也会执行一次彻底删除操作，从而从 100% 的已删除行恢复空间。  
您只能为单个表更改默认 vacuum 阈值。要更改某个表的默认 vacuum 阈值，请包含表名称和 TO *threshold* PERCENT 参数。

SORT ONLY   <a name="vacuum-sort-only"></a>
对指定的表（或当前数据库中的所有表）进行排序，而不回收由删除的表所释放的空间。当回收磁盘空间不重要但对新行进行重新排序很重要时，此选项非常有用。当未排序的区域不包含大量已删除行且不跨整个已排序区域时，SORT ONLY vacuum 将减少 vacuum 操作的运行时间。如果应用程序不具有磁盘空间限制，但依赖于要求表行保持排序状态的查询优化，则可从此类 vacuum 操作获益。  
默认情况下，VACUUM SORT ONLY 将跳过任何至少有 95% 的行已排序的表。要更改某个表的默认排序阈值，请在运行 VACUUM 时包含表名称和 TO *threshold* PERCENT 参数。

DELETE ONLY   <a name="vacuum-delete-only"></a>
Amazon Redshift 在后台自动执行 DELETE ONLY vacuum 操作，因此，您很少需要运行 DELETE ONLY vacuum。  
VACUUM DELETE 回收由前面的 UPDATE 和 DELETE 操作标记为删除的行所占用的磁盘空间，并压缩表以释放占用的空间。DELETE ONLY vacuum 操作不对表数据进行排序。  
当回收磁盘空间很重要但对新行进行重新排序不重要时，此选项可减少 vacuum 操作的运行时间。此外，当查询性能已处于最佳状态，且不要求对行重新排序来优化查询性能时，此选项也很有用。  
默认情况下，VACUUM DELETE ONLY 将回收空间，这样，至少有 95% 的剩余行不会被标记为删除。要更改某个表的默认删除阈值，请在运行 VACUUM 时包含表名称和 TO *threshold* PERCENT 参数。    
一些操作（例如 `ALTER TABLE APPEND`）可能会导致对表进行分片。当您使用 `DELETE ONLY`子句时，vacuum 操作将从分片的表中回收空间。95% 的同一阈值适用于碎片整理操作。

REINDEX  <a name="vacuum-reindex"></a>
分析交错排序键列中的值的分配，然后执行完全 VACUUM 操作。如果使用 REINDEX，则表名称是必需的。  
VACUUM REINDEX 所需的时间显著大于 VACUUM FULL 所需的时间，因为它需要执行额外的过程来分析交错排序键。对于交错表，排序和合并操作所花费的时间更长，因为与复合排序相比，交错排序需要重新排列的行可能更多。  
如果 VACUUM REINDEX 操作在完成前终止，则下一个 VACUUM 将恢复重建索引操作，然后执行完全 vacuum 操作。  
VACUUM REINDEX 不支持 TO *threshold* PERCENT。  

RECLUSTER  <a name="vacuum-recluster"></a>
对表中未排序的部分进行排序。表中已按自动表排序进行排序的部分保持不变。此命令不会将新排序的数据与排序区域合并。也不会回收标记为删除的所有空间。完成此命令后，表可能不会显示完全排序，如 SVV\$1TABLE\$1INFO 中的 `unsorted` 字段所示。  
 我们建议您对具有频繁摄入和仅访问最新数据的查询操作的大型表使用 VACUUM RECLUSTER。  
 VACUUM RECLUSTER 不支持 TO threshold PERCENT。如果使用 RECLUSTER，则表名称是必需的。  
对于具有交错排序键的表和具有 ALL 分配方式的表，不支持 VACUUM RECLUSTER。

 *table\$1name*   
要执行 vacuum 操作的表的名称。如果不指定表名称，vacuum 操作将应用于当前数据库中的所有表。您可以指定任何永久或临时的用户创建的表。此命令对于其他对象（例如，视图和系统表）没有用处。  
 如果包含 TO *threshold* PERCENT 参数，则必须指定表名称。

 TO *threshold* PERCENT   
一个子句，指定超过时 VACUUM 将跳过排序阶段的阈值和删除阶段中回收空间的目标阈值。*排序阈值* 是执行 vacuum 操作之前在指定表中已排序的行占总行数的百分比。 *删除阈值* 是执行 vacuum 操作之后未标记为删除的行占总行数的最小百分比。  
由于 VACUUM 仅会在表中已排序行所占的百分比低于排序阈值时对行进行重新排序，Amazon Redshift 经常可以大幅减少 VACUUM 次数。同样，当 VACUUM 不受限于从 100% 的标记为删除的行回收空间时，它通常能够跳过重写仅包含几个已删除行的数据块的过程。  
例如，如果您为 *threshold* 指定 75，则当表中 75% 或以上的行已有序时，VACUUM 会跳过排序阶段。对于删除阶段，VACUUMS 将设置一个回收磁盘空间的目标，这样，在执行 vacuum 操作之后，表中至少有 75% 的行不会被标记为删除。*threshold* 值必须为介于 0 到 100 之间的整数。默认值为 95。如果您指定了值 100，VACUUM 将始终对表进行排序（除非它已完全排序）并从标记为删除的所有行回收空间。如果您指定的值为 0，则 VACUUM 将从不对表进行排序，也从不会回收空间。  
如果您包含 TO *threshold* PERCENT 参数，则必须同时指定表名称。如果忽略表名称，则 VACUUM 操作将失败。  
您不能将 TO *threshold* PERCENT 参数用于 REINDEX。

BOOST  
使用可用的其他资源（例如内存和磁盘空间）运行 VACUUM 命令。利用 BOOST 选项，VACUUM 在一个窗口中运行，并在 VACUUM 操作期间阻止并发删除和更新。使用 BOOST 选项运行会争用系统资源，这可能会影响查询性能。当系统负载很小时（例如，在维护操作期间），运行 VACUUM BOOST。  
在使用 BOOST 选项时，注意以下事项：  
+ 在指定 BOOST 时，需要 *table\$1name* 值。
+ 不支持将 BOOST 与 REINDEX 结合使用。
+ BOOST 与 DELETE ONLY 结合使用时将被忽略。

## 使用说明
<a name="r_VACUUM_usage_notes"></a>

对于大多数 Amazon Redshift 应用程序，建议执行完全 vacuum 操作。有关更多信息，请参阅 [对表执行 vacuum 操作](t_Reclaiming_storage_space202.md)。

在运行 vacuum 操作之前，请注意以下行为：
+ 您不能在事务数据块 (BEGIN ... END) 中运行 VACUUM。有关事务的更多信息，请参阅 [Amazon Redshift 中的隔离级别](c_serial_isolation.md)。
+ 对表执行 vacuum 操作时，表可能会出现一定量的增长。当没有可回收空间的已删除行时，或者表的新排序顺序导致数据压缩率降低时，这是预期行为。
+ 在 vacuum 操作期间，会出现一定程度的查询性能降级。一旦 vacuum 操作完成，性能就将恢复正常。
+ 并发写入操作可在 vacuum 操作期间执行，但我们不建议在进行 vacuum 操作时执行写入操作。更高效的方法是，先完成写入操作，然后再运行 vacuum 操作。此外，不能对 vacuum 操作开始后写入的任何数据执行此操作。在这种情况下，有必要执行另一个 vacuum 操作。
+ 如果加载或插入操作已在进行中，则 vacuum 操作可能无法开始。Vacuum 操作临时需要表的独占访问权限才能开始。要求此独占访问权限的时间非常短，vacuum 操作不会阻止任何重要时段内的并发加载和插入操作。
+ 当不需要对特定表执行 vacuum 操作时，将跳过 vacuum 操作；不过，发现可跳过该操作会产生一些开销。如果您知道某个表是原始表或未达到 vacuum 阈值，则不要对其运行 vacuum 操作。
+ 对小型表执行 DELETE ONLY vacuum 操作可能不会减少用于存储数据的块数，特别是当表具有大量列或集群为每个节点使用大量切片时。这些 vacuum 操作会按每个切片、每个列增加一个块，来支持对表执行的并行插入；相比通过回收磁盘空间减少块计数带来的好处，产生的开销可能会得不偿失。例如，如果在执行 vacuum 操作之前，一个 8 节点集群中包含 10 列的表占用了 1000 个块，则 vacuum 不会减少实际块计数，除非由于已删除的行导致回收 80 个以上的磁盘空间块。（每个数据块使用 1MB。）

在满足下列任意条件时，自动 vacuum 操作暂停：
+ 用户运行数据定义语言 (DDL) 操作（例如 ALTER TABLE），该操作需要自动 vacuum 当前正在处理的表上的独占锁定。
+ 高集群负载期间。

### 对并发 VACUUM 的支持
<a name="r_VACUUM_usage_notes_concurrent"></a>

Amazon Redshift 支持在集群或工作组中的不同会话上并发运行多个 vacuum 事务。这意味着，您可以一次发出所有 vacuum 模式的不同和多个实例，每个 vacuum 事务都在一个唯一的表上。两个 vacuum 操作不能同时在单个表上运行。

**运行并发 vacuum 的指导原则**
+ 在不同会话中运行并发 vacuum 事务时，应监控系统资源，并避免并发运行过多 vacuum 操作。
+ 建议的并发级别取决于要回收的空间量、要排序的行数和行宽度、仓库的大小以及与 VACUUM 操作一起运行的工作负载的大小。
+ 根据 vacuum 事务的模式，从两个并发 vacuum 操作开始，然后根据它们的运行时间和系统负载添加更多操作。就像用户发出的其它繁重的查询一样，如果您在 Amazon Redshift 达到系统资源限制时并发运行过多 vacuum 操作，则这些操作可能会开始排队。
+ 运行多个 Vacuum BOOST 操作时，请务必小心。使用 BOOST 选项运行 Vacuum 会争用系统资源，这可能会影响查询性能。当系统负载很小时（例如，在维护操作期间），运行 VACUUM BOOST。
+ 如果不指定表名称，vacuum 操作将应用于当前数据库中的所有表。这些 vacuum 操作仍按顺序运行。

## 示例
<a name="r_VACUUM_command-examples"></a>

根据默认的 95% vacuum 阈值回收所有表中的空间和数据库并对这些表中的行进行重新排序。

```
vacuum;
```

根据默认的 95% 阈值回收 SALES 表中的空间并对该表中的行进行重新排序。

```
vacuum sales;
```

始终回收 SALES 表中的空间并对该表中的行进行重新排序。

```
vacuum sales to 100 percent;
```

仅当 SALES 表中有序行的比例低于 75% 时对该表中的行进行重新排序。

```
 vacuum sort only sales to 75 percent;
```

回收 SALES 表中的空间，以使至少 75% 的剩余行不会在 vacuum 操作之后被标记为删除。

```
vacuum delete only sales to 75 percent;
```

为 LISTING 表重建索引，然后对该表执行 vacuum 操作。

```
vacuum reindex listing;
```

以下命令会返回错误。

```
vacuum reindex listing to 75 percent;
```

重建集群，然后对 LISTING 表执行 vacuum 操作。

```
vacuum recluster listing;
```

重建集群，然后使用 BOOST 选项对 LISTING 表执行 vacuum 操作。

```
vacuum recluster listing boost;
```