

 从补丁 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="cm_chap_SQLCommandRef"></a>

借助 Amazon Redshift，您可以利用 SQL 高效地查询和分析存储在数据仓库中的大量数据。SQL 参考资料涵盖 SQL 命令、数据类型、函数、运算符等的语法和用法，使您能够提取见解并做出数据驱动的决策。您可以查阅此参考资料来编写优化的查询、创建和管理数据库对象以及执行复杂的数据转换。以下参考资料提供了有关在 Amazon Redshift 环境中使用 SQL 来满足您的数据分析要求的全面详细信息。

**Topics**
+ [Amazon Redshift SQL](c_redshift-sql.md)
+ [使用 SQL](c_SQL_reference.md)
+ [SQL 命令](c_SQL_commands.md)
+ [SQL 函数参考](c_SQL_functions.md)
+ [保留字](r_pg_keywords.md)

# Amazon Redshift SQL
<a name="c_redshift-sql"></a>

**Topics**
+ [在领导节点上支持的 SQL 函数](c_sql-functions-leader-node.md)
+ [Amazon Redshift 和 PostgreSQL](c_redshift-and-postgres-sql.md)

Amazon Redshift 是围绕行业标准 SQL 构建的，新增了管理非常大的数据库并支持针对这些数据进行高性能分析和报告的功能。

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

# 在领导节点上支持的 SQL 函数
<a name="c_sql-functions-leader-node"></a>

一些 Amazon Redshift 查询是在计算节点上分发和运行的；而另一些查询仅在领导节点上运行。

每当查询引用用户创建的表或系统表（具有 STL 或 STV 前缀的表和具有 SVL 或 SVV 前缀的系统视图）时，领导节点就会将 SQL 分发到计算节点。仅引用目录表（驻留在领导节点上的、具有 PG 前缀的表，如 PG\$1TABLE\$1DEF）或不引用任何表的查询在领导节点上以独占方式运行。

部分 Amazon Redshift SQL 函数仅在领导节点上受支持，在计算节点上不受支持。使用领导节点函数的查询必须在领导节点上而不是计算节点上以独占方式执行，否则它将返回错误。

必须在领导节点上以独占方式运行的每个函数的文档包含一个注释，指示该函数将在引用用户定义的表或 Amazon Redshift 系统表时返回错误。有关在领导节点上以独占方式运行的函数的列表，请参阅[仅领导节点函数](c_SQL_functions_leader_node_only.md)。

## 示例
<a name="c_sql-functions-leader-node-examples"></a>

以下示例使用示例 TICKIT 数据库。有关示例数据库的更多信息，请转到[示例数据库](c_sampledb.md)。

**CURRENT\$1SCHEMA**

CURRENT\$1SCHEMA 函数是仅适用于领导节点的函数。在此示例中，查询不会引用表，因此它将在领导节点上以独占方式运行。

```
select current_schema();
            
current_schema
---------------
public
```

在下一个示例中，查询引用系统目录表，因此它将在领导节点上以独占方式运行。

```
select * from pg_table_def
where schemaname = current_schema() limit 1;

 schemaname | tablename | column |   type   | encoding | distkey | sortkey | notnull
------------+-----------+--------+----------+----------+---------+---------+---------
 public     | category  | catid  | smallint | none     | t       |       1 | t
```

在下一个示例中，查询引用驻留在计算节点上的 Amazon Redshift 系统表，因此它将返回错误。

```
select current_schema(), userid from users;

INFO:  Function "current_schema()" not supported.
ERROR:  Specified types or functions (one per INFO message) not supported on Amazon Redshift tables.
```

**SUBSTR**

SUBSTR 也是一个仅适用于领导节点的函数。在下面的示例中，由于查询没有引用表，因此在领导节点上以独占方式运行。

```
SELECT SUBSTR('amazon', 5);
            
+--------+
| substr |
+--------+
| on     |
+--------+
```

在下面的示例中，查询引用驻留在计算节点上的表。这会导致错误。

```
SELECT SUBSTR(catdesc, 1) FROM category LIMIT 1;
            
ERROR: SUBSTR() function is not supported (Hint: use SUBSTRING instead)
```

要成功运行前一个查询，请使用 [SUBSTRING](https://docs.aws.amazon.com/redshift/latest/dg/r_SUBSTRING.html)。

```
SELECT SUBSTRING(catdesc, 1) FROM category LIMIT 1;
            
+---------------------------------+
|            substring            |
+---------------------------------+
| National Basketball Association |
+---------------------------------+
```

**FACTORIAL()**

FACTORIAL() 是仅适用于主节点的函数。在下面的示例中，由于查询没有引用表，因此在领导节点上以独占方式运行。

```
SELECT FACTORIAL(5);           

 factorial 
-------------
 120
```

在下面的示例中，查询引用驻留在计算节点上的表。使用查询编辑器 v2 运行时会导致错误。

```
create table t(a int);
insert into t values (5);
select factorial(a) from t;           

ERROR: Specified types or functions (one per INFO message) not supported on Redshift tables.
Info: Function "factorial(bigint)" not supported.
```

# Amazon Redshift 和 PostgreSQL
<a name="c_redshift-and-postgres-sql"></a>

**Topics**
+ [Amazon Redshift 及 PostgreSQL JDBC 和 ODBC](c_redshift-postgres-jdbc.md)
+ [以不同方式实施的功能](c_redshift-sql-implementated-differently.md)
+ [不支持的 PostgreSQL 功能](c_unsupported-postgresql-features.md)
+ [不支持的 PostgreSQL 数据类型](c_unsupported-postgresql-datatypes.md)
+ [不支持的 PostgreSQL 函数](c_unsupported-postgresql-functions.md)

Amazon Redshift 基于 PostgreSQL。Amazon Redshift 和 PostgreSQL 之间的差别非常大，您在设计和开发数据仓库应用程序时必须注意这一点。

Amazon Redshift 是专为联机分析处理 (OLAP) 和业务智能 (BI) 应用程序设计的，这些应用程序需要针对大型数据集的复杂查询。由于它解决了迥然不同的需求，因此 Amazon Redshift 使用的专用数据存储 schema 和查询执行引擎完全不同于 PostgreSQL 实现。例如，联机事务处理 (OLTP) 应用程序通常将数据存储在行中，Amazon Redshift 将数据存储在列中，并使用专业的数据压缩编码以获得最优的内存使用和磁盘输入/输出。某些适合小型 OLTP 处理，如二级索引和高效单行数据操作运算的 PostgreSQL 功能已省略，以改进性能。

有关 Amazon Redshift 数据仓库系统架构的详细解释，请参阅[Amazon Redshift 架构](c_redshift_system_overview.md)。

PostgreSQL 9.x 包含一些在 Amazon Redshift 中不支持的功能。此外，Amazon Redshift SQL 和 PostgreSQL 之间有一些重大差异，您必须了解。本节重点介绍了 Amazon Redshift 和 PostgreSQL 之间的差异，并提供了开发充分利用 Amazon Redshift SQL 实现的数据仓库的指南。

# Amazon Redshift 及 PostgreSQL JDBC 和 ODBC
<a name="c_redshift-postgres-jdbc"></a>

 由于 Amazon Redshift 基于 PostgreSQL，因此我们之前建议使用 JDBC4 Postgresql 驱动程序版本 8.4.703 和 psqlODBC 版本 9.x 的驱动程序。如果您当前使用的是这两种驱动程序，建议您接下来转移至新的特定于 Amazon Redshift 的驱动程序。有关驱动程序和配置连接的更多信息，请参阅《Amazon Redshift 管理指南》**中的 [Amazon Redshift 的 JDBC 和 ODBC 驱动程序](https://docs.aws.amazon.com/redshift/latest/mgmt/configuring-connections.html#connecting-drivers)。

为了避免在使用 JDBC 检索大型数据集时出现客户端内存不足错误，您可通过设置 JDBC 提取大小参数来使您的客户端能够成批提取数据。有关更多信息，请参阅 [设置 JDBC 提取大小参数](set-the-JDBC-fetch-size-parameter.md)。

Amazon Redshift 无法识别 JDBC maxRows 参数。请改为指定 [LIMIT](r_ORDER_BY_clause.md#order-by-clause-limit) 子句来限制结果集。您还可使用 [OFFSET](r_ORDER_BY_clause.md#order-by-clause-offset) 子句跳至结果集中的特定起点。

# 以不同方式实施的功能
<a name="c_redshift-sql-implementated-differently"></a>

许多 Amazon Redshift SQL 语言元素都具有不同的性能特征和使用语法以及语义，并且等效的 PostgreSQL 实施有很大不同。

**重要**  
请勿假设 Amazon Redshift 和 PostgreSQL 共同具有的元素的语义是相同的。确保查阅《Amazon Redshift 开发人员指南》**[SQL 命令](c_SQL_commands.md)以了解常有的细小差异。

一个具体的示例是 [VACUUM](r_VACUUM_command.md) 命令，该命令用于清理和重新组织表。VACUUM 具有不同的功能，并且使用的参数组不同于 PostgreSQL 版本。有关在 Amazon Redshift 中使用 VACUUM 的更多信息，请参阅[对表执行 vacuum 操作](t_Reclaiming_storage_space202.md)。

通常，数据库管理功能和工具也不相同。例如，Amazon Redshift 维护一组提供有关系统运行方式的信息的系统表和视图。参阅 [SYS 监控视图](serverless_views-monitoring.md) 了解更多信息。

以下列表包含 Amazon Redshift 中的实现方式不同的 SQL 功能的一些示例。
+  [CREATE TABLE](r_CREATE_TABLE_NEW.md) 

  Amazon Redshift 不支持表空间、表分区、继承和某些约束。CREATE TABLE 的 Amazon Redshift 实现使您能够为表定义排序和分配算法以优化并行处理。

  Amazon Redshift Spectrum 支持使用 [CREATE EXTERNAL TABLE](r_CREATE_EXTERNAL_TABLE.md) 命令的表分区。
+  [ALTER TABLE](r_ALTER_TABLE.md) 

  只支持 ALTER COLUMN 操作的子集。

  ADD COLUMN 支持在每个 ALTER TABLE 语句中仅添加一列。
+  [COPY](r_COPY.md) 

  Amazon Redshift COPY 命令专门用于支持从 Amazon S3 桶和 Amazon DynamoDB 表加载数据以及方便自动压缩。有关详细信息，请参阅[在 Amazon Redshift 中加载数据](t_Loading_data.md)部分和 COPY 命令参考。
+  [VACUUM](r_VACUUM_command.md) 

  VACUUM 的参数完全不同。例如，PostgreSQL 中的默认 VACUUM 操作只是回收空间并使空间可供重复使用；但是，Amazon Redshift 中的默认 VACUUM 操作为 VACUUM FULL，可回收磁盘空间并对所有行重新排序。
+ 在比较字符串值时，会忽略 VARCHAR 值的尾部空格。有关更多信息，请参阅 [尾部空格的意义](r_Character_types.md#r_Character_types-significance-of-trailing-blanks)。

# 不支持的 PostgreSQL 功能
<a name="c_unsupported-postgresql-features"></a>

这些功能在 Amazon Redshift 中不受支持。

**重要**  
请勿假设 Amazon Redshift 和 PostgreSQL 共同具有的元素的语义是相同的。确保查阅《Amazon Redshift 开发人员指南》**[SQL 命令](c_SQL_commands.md)以了解常有的细小差异。
+ 不支持查询工具 *RSQL*。支持 [Amazon Redshift RSQL](https://docs.aws.amazon.com/redshift/latest/mgmt/rsql-query-tool.html) 客户端。
+ 表分区（范围和列表分区）
+ 表空间
+ 约束
  + 唯一
  + 外键
  + 主键
  + 检查约束
  + 排他性约束

  允许唯一键、主键和外键约束，但它们仅供参考。这些约束不由系统强制实施，而是由查询规划器使用。
+ 继承
+ PostgreSQL 系统列

  Amazon Redshift SQL 不会隐式定义系统列。但是，以下 PostgreSQL 系统列名称无法用作用户定义列的名称：`oid`、`tableoid`、`xmin`、`cmin`、`xmax`、`cmax` 和 `ctid`。有关更多信息，请参阅 [https://www.postgresql.org/docs/8.0/static/ddl-system-columns.html](https://www.postgresql.org/docs/8.0/static/ddl-system-columns.html)。
+ 索引
+ 窗口函数中的 NULLS 子句
+ 排序规则

  Amazon Redshift 不支持区域设置特定的或用户定义的排序规则序列。请参阅 [排序规则序列](c_collation_sequences.md)。
+ 值表达式
  + 下标表达式
  + 数组构造函数
  + 行构造函数
+ 触发
+ 外部数据管理 (SQL/MED)
+ 表函数
+ 用作常量表的 VALUES 列表
+ Sequences 属性
+ 全文搜索
+ RULE 和 TRIGGER 权限。

  当您运行 GRANT ALL 或 REVOKE ALL 时，Amazon Redshift 会授予或撤销这些权限，但是 RULE 和 TRIGGER 权限的存在与否不会以任何方式影响被授权者的访问权限。

# 不支持的 PostgreSQL 数据类型
<a name="c_unsupported-postgresql-datatypes"></a>

通常，如果查询尝试使用不受支持的数据类型，包括显式或隐式强制转换，则将返回错误。但是，使用不支持的数据类型的某些查询将仅在领导节点运行，而不在计算节点上运行。请参阅 [在领导节点上支持的 SQL 函数](c_sql-functions-leader-node.md)。

 有关支持的数据类型的列表，请参阅[数据类型](c_Supported_data_types.md)。

这些 PostgreSQL 数据类型在 Amazon Redshift 中不受支持。
+ 数组
+ BIT、BIT VARYING
+ BYTEA
+ 复合类型
+ 枚举类型
+ 几何类型（Amazon Redshift 对几何类型的实现与 PostgreSQL 不同）
+ HSTORE
+ JSON
+ 网络地址类型
+ 数字类型
  + SERIAL、BIGSERIAL、SMALLSERIAL
  + MONEY
+ 对象标识符类型
+ 伪类型
+ 范围类型
+ 特殊字符类型
  + “char” – 单字节内部类型（其中名为 char 的数据类型用引号括起来）。
  + name – 对象名称的内部类型。

  有关这些类型的更多信息，请参阅 PostgreSQL 文档中的[特殊字符类型](https://www.postgresql.org/docs/8.0/datatype-character.html)。
+ 文本搜索类型
+ TXID\$1SNAPSHOT
+ UUID
+ XML

# 不支持的 PostgreSQL 函数
<a name="c_unsupported-postgresql-functions"></a>

很多未排除的函数具有不同的语义或用法。例如，一些受支持的函数将仅在领导节点上运行。此外，一些不受支持的函数在领导节点上运行时不会返回错误。这些函数在某些情况下不返回错误的情况不应视为表示这些函数受 Amazon Redshift 支持。

**重要**  
请勿假设 Amazon Redshift 和 PostgreSQL 共同具有的元素的语义是相同的。确保查阅《Amazon Redshift 数据库开发人员指南》**[SQL 命令](c_SQL_commands.md)以了解常有的细小差异。

 有关更多信息，请参阅 [在领导节点上支持的 SQL 函数](c_sql-functions-leader-node.md)。

这些 PostgreSQL 函数在 Amazon Redshift 中不受支持。
+ 访问权限查询函数
+ 劝告锁函数
+ 聚合函数
  + STRING\$1AGG()
  + ARRAY\$1AGG()
  + EVERY()
  + XML\$1AGG()
  + CORR()
  + COVAR\$1POP()
  + COVAR\$1SAMP()
  + REGR\$1AVGX()、REGR\$1AVGY()
  + REGR\$1COUNT()
  + REGR\$1INTERCEPT()
  + REGR\$1R2()
  + REGR\$1SLOPE()
  + REGR\$1SXX()、REGR\$1SXY()、REGR\$1SYY()
+ 数组函数和运算符
+ 备份控制函数
+ 注释信息函数
+ 数据库对象位置函数
+ 数据库对象大小函数
+ 日期/时间函数和运算符
  + CLOCK\$1TIMESTAMP()
  + JUSTIFY\$1DAYS()、JUSTIFY\$1HOURS()、JUSTIFY\$1INTERVAL()
  + PG\$1SLEEP()
  + TRANSACTION\$1TIMESTAMP()
+ ENUM 支持函数
+ 几何函数和运算符
+ 一般文件访问函数
+ IS DISTINCT FROM
+ 网络地址函数和运算符
+ 数学函数
  + DIV()
  + SETSEED()
  + WIDTH\$1BUCKET()
+ 设置返回函数
  + GENERATE\$1SERIES()
  + GENERATE\$1SUBSCRIPTS()
+ 范围函数和运算符
+ 恢复控制函数
+ 恢复信息函数
+ ROLLBACK TO SAVEPOINT 函数
+ Schema 可见性查询函数
+ 服务器信号函数
+ 快照同步函数
+ 顺序操作函数
+ 字符串函数
  + BIT\$1LENGTH()
  + OVERLAY()
  + CONVERT()、CONVERT\$1FROM()、CONVERT\$1TO()
  + ENCODE()
  + FORMAT()
  + QUOTE\$1NULLABLE()
  + REGEXP\$1MATCHES()
  + REGEXP\$1SPLIT\$1TO\$1ARRAY()
  + REGEXP\$1SPLIT\$1TO\$1TABLE()
+ 系统目录信息函数
+ 系统信息函数
  + CURRENT\$1CATALOG CURRENT\$1QUERY()
  + INET\$1CLIENT\$1ADDR()
  + INET\$1CLIENT\$1PORT()
  + INET\$1SERVER\$1ADDR() INET\$1SERVER\$1PORT()
  + PG\$1CONF\$1LOAD\$1TIME()
  + PG\$1IS\$1OTHER\$1TEMP\$1SCHEMA()
  + PG\$1LISTENING\$1CHANNELS()
  + PG\$1MY\$1TEMP\$1SCHEMA()
  + PG\$1POSTMASTER\$1START\$1TIME()
  + PG\$1TRIGGER\$1DEPTH()
  + SHOW VERSION()
+ 文本搜索函数和运算符
+ 事务 ID 和快照函数
+ 触发器函数
+ XML 函数

# 使用 SQL
<a name="c_SQL_reference"></a>

**Topics**
+ [SQL 参考惯例](c_SQL_reference_conventions.md)
+ [基本元素](c_Basic_elements.md)
+ [表达式](r_expressions.md)
+ [条件](r_conditions.md)

SQL 语言由您用于处理数据库和数据库对象的命令和函数组成。该语言还会强制实施有关数据类型、表达式和文本使用的规则。

# SQL 参考惯例
<a name="c_SQL_reference_conventions"></a>

此部分介绍用于为 SQL 参考部分中介绍的 SQL 表达式、命令和函数编写语法的约定。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/c_SQL_reference_conventions.html)

# 基本元素
<a name="c_Basic_elements"></a>

**Topics**
+ [名称和标识符](r_names.md)
+ [文本](r_Literals.md)
+ [null](r_Nulls.md)
+ [数据类型](c_Supported_data_types.md)
+ [排序规则序列](c_collation_sequences.md)

本部分介绍了用于处理数据库对象名称、文本、null 和数据类型的规则。

# 名称和标识符
<a name="r_names"></a>

名称用于标识数据库对象，包括表和列以及用户和密码。*名称* 和*标识符* 这两个术语可互换使用。有两种类型的标识符：标准标识符以及带引号的标识符或分隔标识符。标识符必须仅包含 UTF-8 可打印字符。标准标识符和分隔标识符中的 ASCII 字母是不区分大小写的，并且会在数据库中转换为小写。默认情况下，查询结果中的列名称以小写形式返回。要以大写形式返回列名称，请将 [describe\$1field\$1name\$1in\$1uppercase](r_describe_field_name_in_uppercase.md) 配置参数设置为 **true**。

## 标准标识符
<a name="r_names-standard-identifiers"></a>

标准 SQL 标识符遵循一组规则并且必须：
+ 以 ASCII 单字节字母字符或下划线字符开头，或者以 UTF-8 多字节字符（长度为 2 到 4 字节）开头。
+ 后续字符可以是 ASCII 单字节字母数字字符、下划线或美元符号，或者 UTF-8 多字节字符 (两到四字节长)。
+ 长度介于 1 到 127 个字节之间，不包含分隔标识符的引号。
+ 不包含引号和空格。
+ 不是保留的 SQL 关键字。

## 分隔标识符
<a name="r_names-delimited-identifiers"></a>

分隔标识符（也称为“带引号的标识符”）以双引号 (") 开头和结尾。如果您使用分隔标识符，则必须在每次引用对象时使用双引号。标识符可包含双引号以外的任何标准 UTF-8 可打印字符。因此，您可创建包含非法字符的列或表名称，如空格或百分比符号。

分隔标识符中的 ASCII 字母是不区分大小写的，并且会转换为小写。要在字符串中使用双引号，您必须在字符串前加上另一个双引号字符。

## 区分大小写的标识符
<a name="r_names-case-sensitive-identifiers"></a>

区分大小写的标识符（也称为混合大小写标识符）可以包含大写字母和小写字母。要使用区分大小写的标识符，可您可以将配置 `enable_case_sensitive_identifier` 设置为 `true`。您可以为集群或会话设置此配置。有关更多信息，请参阅《Amazon Redshift 管理指南》**中的[默认参数值](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-parameter-groups.html#default-param-group-values)和[enable\$1case\$1sensitive\$1identifier](r_enable_case_sensitive_identifier.md)。

## 系统列名称
<a name="r_names-system-column-names"></a>

以下 PostgreSQL 系统列名称无法用作用户定义列中的列名称。有关更多信息，请参阅 [https://www.postgresql.org/docs/8.0/static/ddl-system-columns.html](https://www.postgresql.org/docs/8.0/static/ddl-system-columns.html)。
+ `oid`
+ `tableoid`
+ `xmin`
+ `cmin`
+ `xmax`
+ `cmax`
+ `ctid`

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

此表显示了分隔标识符的示例、生成的输出和讨论：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_names.html)

创建一个名为 group 的表，其中一列的名称为 this "is it"：

```
create table "group" (
"This ""IS IT""" char(10));
```

下面的查询返回相同的结果：

```
select "This ""IS IT"""
from "group";

this "is it"
--------------
(0 rows)
```

```
select "this ""is it"""
from "group";

this "is it"
--------------
(0 rows)
```

以下完全限定的 `table.column` 语法也返回相同的结果：

```
select "group"."this ""is it"""
from "group";

this "is it"
--------------
(0 rows)
```

以下 CREATE TABLE 命令创建一个表，其中的一个列名包含斜杠：

```
create table if not exists city_slash_id(
                  "city/id" integer not null,
                  state char(2) not null);
```

# 文本
<a name="r_Literals"></a>

文本或常量是固定数据值，由一系列字符或数字常量组成。Amazon Redshift 支持多种文本，包括：
+ 整数、小数和浮点数的数字文本。有关更多信息，请参阅 [整数和浮点文本](r_numeric_literals201.md)。
+ 字符文本，也称为“字符串”或“字符常量”
+ 与日期时间数据类型一起使用的日期时间和间隔文本。有关更多信息，请参阅[日期、时间和时间戳文本](r_Date_and_time_literals.md)和[间隔数据类型和文字](r_interval_data_types.md)。

# null
<a name="r_Nulls"></a>

如果行中有某个列缺失、未知或不适用，则该列为 null 值，或者说该列包含 null。null 可出现在不受主键或 NOT NULL 约束限制的任何数据类型的字段中。null 不等于零值或空字符串。

任何包含 null 的算术表达式的计算结果始终为 null。所有运算符在给定 null 参数或操作数的情况下均返回 null。

要测试是否为 null，请使用比较条件 IS NULL 和 IS NOT NULL。由于 null 表示缺少数据，因此 null 不等于任何值或其他 null。

# 数据类型
<a name="c_Supported_data_types"></a>

**Topics**
+ [多字节字符](#c_Supported_data_types-multi-byte-characters)
+ [数字类型](r_Numeric_types201.md)
+ [字符类型](r_Character_types.md)
+ [日期时间类型](r_Datetime_types.md)
+ [布尔值类型](r_Boolean_type.md)
+ [HLLSKETCH 类型](r_HLLSKTECH_type.md)
+ [SUPER 类型](r_SUPER_type.md)
+ [VARBYTE 类型](r_VARBYTE_type.md)
+ [类型兼容性和转换](#r_Type_conversion)

Amazon Redshift 存储或检索的每个值都具有包含一组固定关联属性的数据类型。数据类型是在创建表时声明的。数据类型约束了列或参数可包含的一组值。

下表列出了您可在 Amazon Redshift 表中使用的数据类型。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/c_Supported_data_types.html)

**注意**  
有关不支持的数据类型的信息，例如“char”（注意 char 用引号括起来），请参阅[不支持的 PostgreSQL 数据类型](c_unsupported-postgresql-datatypes.md)。

## 多字节字符
<a name="c_Supported_data_types-multi-byte-characters"></a>

VARCHAR 数据类型支持多达 4 个字节的 UTF-8 多字节字符。不支持 5 个字节或更长的字符。要计算包含多字节字符的 VARCHAR 列的大小，请用字符数乘以每个字符的字节数。例如，如果一个字符串包含四个中文字符，并且每个字符的长度为三个字节，则您需要一个 VARCHAR(12) 列才能存储该字符串。

VARCHAR 数据类型不支持下列无效的 UTF-8 代码点：

`0xD800 – 0xDFFF`（字节序列：`ED A0 80` –`ED BF BF` ）

CHAR 数据类型不支持多字节字符。

# 数字类型
<a name="r_Numeric_types201"></a>

**Topics**
+ [整数类型](#r_Numeric_types201-integer-types)
+ [DECIMAL 或 NUMERIC 类型](#r_Numeric_types201-decimal-or-numeric-type)
+ [有关使用 128 位 DECIMAL 或 NUMERIC 列的说明](#r_Numeric_types201-notes-about-using-128-bit-decimal-or-numeric-columns)
+ [浮点类型](#r_Numeric_types201-floating-point-types)
+ [数值计算](r_numeric_computations201.md)
+ [整数和浮点文本](r_numeric_literals201.md)
+ [数字类型的示例](r_Examples_with_numeric_types201.md)

数字数据类型包括整数、小数和浮点数。

## 整数类型
<a name="r_Numeric_types201-integer-types"></a>

使用 SMALLINT、INTEGER 和 BIGINT 数据类型存储各种范围的整数。您无法存储每种类型所允许范围之外的值。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Numeric_types201.html)

## DECIMAL 或 NUMERIC 类型
<a name="r_Numeric_types201-decimal-or-numeric-type"></a>

使用 DECIMAL 或 NUMERIC 数据类型存储具有*用户定义的精度* 的值。DECIMAL 和 NUMERIC 关键字是可互换的。在本文档中，*小数* 是此数据类型的首选术语。术语*数字* 一般用于指整数、小数和浮点数据类型。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Numeric_types201.html)

通过指定*精度* 和*小数位数* 来定义表中的 DECIMAL 列：

```
decimal(precision, scale)
```

 *精度*   
整个值中有效位的总数：小数点两边的位数。例如，数字 `48.2891` 的精度为 6，小数位数为 4。如果未指定，默认精度为 18。最大精度为 38。  
 如果输入值中的小数点左侧的位数超出了列的精度减去其小数位数的差值，则此值无法复制到列中（或无法插入或更新）。此规则适用于列定义范围之外的任何值。例如，`numeric(5,2)` 列所允许的值范围为 `-999.99` 到 `999.99`。

 *小数位数*   
值的小数部分中小数点右侧的小数位数。整数的小数位数为零。在列规范中，小数位数值必须小于或等于精度值。如果未指定，默认小数位数为 0。最大小数位数为 37。  
如果加载到表中的输入值的小数位数大于列的小数位数，则该值将四舍五入到指定小数位数。例如，SALES 表中的 PRICEPAID 列为 DECIMAL(8,2) 列。如果将 DECIMAL(8,4) 值插入到 PRICEPAID 列中，则该值将四舍五入到小数位数 2。  

```
insert into sales
values (0, 8, 1, 1, 2000, 14, 5, 4323.8951, 11.00, null);

select pricepaid, salesid from sales where salesid=0;

pricepaid | salesid
-----------+---------
4323.90 |       0
(1 row)
```
 但是，对于显示强制转换表中选定的值而得出的结果，不会进行四舍五入。

**注意**  
您可插入到 DECIMAL(19,0) 列中的最大正值为 `9223372036854775807` (263 -1)。最大负值为 `-9223372036854775808`。例如，尝试插入值 `9999999999999999999`（19 个 9）将导致溢出错误。无论小数点的位置如何，Amazon Redshift 可表示为 DECIMAL 数的最大字符串为 `9223372036854775807`。例如，您可加载到 DECIMAL(19,18) 列中的最大值为 `9.223372036854775807`。  
这些规则是因为有效精度位为 19 位或更少的 DECIMAL 值在内部存储为 8 字节整数，而有效精度位为 20 到 38 位的 DECIMAL 值存储为 16 字节整数。

## 有关使用 128 位 DECIMAL 或 NUMERIC 列的说明
<a name="r_Numeric_types201-notes-about-using-128-bit-decimal-or-numeric-columns"></a>

请勿为 DECIMAL 列随意分配最高精度，除非您确定您的应用程序需要此精度。128 位值使用的磁盘空间是 64 位值的两倍，并且可能会降低查询执行速度。

## 浮点类型
<a name="r_Numeric_types201-floating-point-types"></a>

使用 REAL 和 DOUBLE PRECISION 数据类型可存储具有*可变精度* 的数值。这些类型是*不精确的* 类型，意味着一些值是作为估计值存储的，因此存储和返回某个特定值可能导致细微的差异。如果您需要精确的存储和计算（如货币金额），请使用 DECIMAL 数据类型。

根据 IEEE 二进制浮点运算标准 754，REAL 表示单精度浮点数格式。它的精度约为 6 位，范围在 1E-37 到 1E\$137 之间。您也可以将此数据类型指定为 FLOAT4。

根据 IEEE 二进制浮点运算标准 754，DOUBLE PRECISION 表示双精度浮点数格式。它的精度约为 15 位，范围在 1E-307 到 1E\$1308 之间。您也可以将此数据类型指定为 FLOAT 或 FLOAT8。

除普通数值外，浮点型还有几个特殊值。在 SQL 中使用这些值时，请在这些值周围使用单引号：
+ `NaN` – 非数字
+ `Infinity` – 无穷大
+ `-Infinity` – 负无穷大

例如，要在表 `customer_activity` 的列 `day_charge` 中插入非数字，请运行以下 SQL：

```
insert into customer_activity(day_charge) values('NaN');
```

# 数值计算
<a name="r_numeric_computations201"></a>

在此上下文中，*计算* 指二进制数学运算：加、减、乘、除。此部分介绍这些运算的预期返回类型，以及在涉及 DECIMAL 数据类型时应用于确定精度和小数位数的特定公式。

当在查询处理期间计算数值时，您可能会遇到无法计算和查询返回数字溢出错误的情况。您还可能会遇到计算值的小数位数发生变化或出乎意料的情况。对于一些运算，您可使用显式强制转换（类型提升）或 Amazon Redshift 配置参数来解决这些问题。

有关类似使用 SQL 函数的计算的结果的信息，请参阅[聚合函数](c_Aggregate_Functions.md)。

## 计算的返回类型
<a name="r_numeric_computations201-return-types-for-computations"></a>

提供 Amazon Redshift 中支持的一组数字数据类型，下表中显示了加、减、乘、除运算的预期返回类型。表左侧第一列表示计算中的第一个操作数，顶部行表示第二个操作数。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_numeric_computations201.html)

## 计算的 DECIMAL 结果的精度和小数位数
<a name="r_numeric_computations201-precision-and-scale-of-computed-decimal-results"></a>

下表汇总了在数学运算返回 DECIMAL 结果时用于计算生成的精度和小数位数的规则。在此表中，`p1` 和 `s1` 分别表示计算中第一个操作数的精度和小数位数，`p2` 和 `s2` 分别表示第二个操作数的精度和小数位数。（不管这些计算如何，最大的结果精度为 38，最大的结果小数位数为 38）。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_numeric_computations201.html)

例如，SALES 表中的 PRICEPAID 和 COMMISSION 列均为 DECIMAL(8,2) 列。如果您用 PRICEPAID 除以 COMMISSION（或者反过来），采用的公式如下所示：

```
Precision = 8-2 + 2 + max(4,2+8-2+1)
= 6 + 2 + 9 = 17

Scale = max(4,2+8-2+1) = 9

Result = DECIMAL(17,9)
```

以下计算是使用集合运算符（如 UNION、INTERSECT 和 EXCEPT）或 COALESCE 和 DECODE 等函数计算对 DECIMAL 值执行的运算的最终精度和小数位数的一般规则：

```
Scale = max(s1,s2)
Precision = min(max(p1-s1,p2-s2)+scale,19)
```

例如，具有一个 DECIMAL(7,2) 列的 DEC1 表将与具有一个 DECIMAL(15,3) 列的 DEC2 表联接以创建 DEC3 表。DEC3 的 schema 表明该列变成了 NUMERIC(15,3) 列。

```
create table dec3 as select * from dec1 union select * from dec2;
```

结果 

```
select "column", type, encoding, distkey, sortkey
from pg_table_def where tablename = 'dec3';

column |     type      | encoding | distkey | sortkey 
-------+---------------+----------+---------+---------
c1     | numeric(15,3) | none     | f       | 0
```

在上例中，采用的公式如下所示：

```
Precision = min(max(7-2,15-3) + max(2,3), 19)
= 12 + 3 = 15

Scale = max(2,3) = 3

Result = DECIMAL(15,3)
```

## 有关除法运算的说明
<a name="r_numeric_computations201-notes-on-division-operations"></a>

对于除法运算，被零除条件将返回错误。

在计算精度和小数位数之后，将应用小数位数最多为 100 的限制。如果计算所得的结果小数位数大于 100，则除法运算结果的范围如下所示：
+ 精度 = ` precision - (scale - max_scale)` 
+ 小数位数 = ` max_scale ` 

如果计算所得的精度大于最大精度 (38)，则精度将减少为 38，小数位数的结果将介于以下范围：`max((38 + scale - precision), min(4, 100))`

## 溢出条件
<a name="r_numeric_computations201-overflow-conditions"></a>

将检查所有数值计算是否存在溢出情况。精度为 19 或 19 以下的 DECIMAL 数据存储为 64 位整数。精度大于 19 的 DECIMAL 数据存储为 128 位整数。所有 DECIMAL 值的最大精度为 38，最大小数位数为 37。当值超出这些限制时将出现溢出错误，中间结果集和最终结果集都存在这种情况：
+ 当特定数据值不符合强制转换函数指定的请求精度或小数位数时，显式强制转换将生成运行时溢出错误。例如，您无法强制转换 SALES 表中 PRICEPAID 列（DECIMAL(8,2) 列）的所有值并返回 DECIMAL(7,3) 结果：

  ```
  select pricepaid::decimal(7,3) from sales;
  ERROR:  Numeric data overflow (result precision)
  ```

  此错误出现的原因是 PRICEPAID 列中的*一些* 较大的值无法强制转换。
+ 乘法运算的乘积结果中的小数位数为所有操作数的小数位数之和。例如，如果两个操作数的小数位数都为 4，则结果的小数位数为 8，小数点左侧仅剩下 10 位。因此，在具有有效小数位数的两个大数相乘时，遇到溢出的情况相对容易一些。

  以下代码会导致溢出错误：

  ```
  SELECT CAST(1 AS DECIMAL(38, 20)) * CAST(10 AS DECIMAL(38, 20));
  ERROR: 128 bit numeric data overflow (multiplication)
  ```

  可以通过使用除法而不是乘法来解决溢出错误。使用以下示例除以 1 与原始除数相除的商。

  ```
  SELECT CAST(1 AS DECIMAL(38, 20)) / (1 / CAST(10 AS DECIMAL(38, 20)));
  +----------+
  | ?column? |
  +----------+
  | 10       |
  +----------+
  ```

## INTEGER 和 DECIMAL 类型的数值计算
<a name="r_numeric_computations201-numeric-calculations-with-integer-and-decimal-types"></a>

如果计算中的一个操作数具有 INTEGER 数据类型且另一个操作数为 DECIMAL，则 INTEGER 操作数将隐式强制转换为 DECIMAL：
+ INT2 (SMALLINT) 将强制转换为 DECIMAL(5,0) 
+ INT4 (INTEGER) 将强制转换为 DECIMAL(10,0) 
+ INT8 (BIGINT) 将强制转换为 DECIMAL(19,0) 

例如，如果将 SALES.COMMISSION（DECIMAL(8,2) 列）和 SALES.QTYSOLD（SMALLINT 列）相乘，则此计算将强制转换为：

```
DECIMAL(8,2) * DECIMAL(5,0)
```

# 整数和浮点文本
<a name="r_numeric_literals201"></a>

表示数字的文本或常量可以是整数或浮点。

## 整数文本
<a name="r_numeric_literals201-integer-literals"></a>

整数常量是一系列 0-9 的数字，并且数字前带有可选的正号 (\$1) 或负号 (-)。

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

```
[ + | - ] digit ...
```

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

有效整数包括以下值：

```
23
-555
+17
```

## 浮点文本
<a name="r_numeric_literals201-floating-point-literals"></a>

浮点文本（也称为“小数、数字或分数文本”）是一系列可包含小数点和指数标记 (e)（可选）的数字。

## 语法
<a name="r_numeric_literals201-synopsis2"></a>

```
[ + | - ] digit ... [ . ] [ digit ...]
[ e | E [ + | - ] digit ... ]
```

## 参数
<a name="r_numeric_literals201-arguments"></a>

e \$1 E  
e 或 E 表示使用科学记数法指定的数字。

## 示例
<a name="r_numeric_literals201-examples2"></a>

有效的浮点文本包括以下值：

```
3.14159
-37.
2.0e19
-2E-19
```

# 数字类型的示例
<a name="r_Examples_with_numeric_types201"></a>



## CREATE TABLE 语句
<a name="r_Examples_with_numeric_types201-create-table-statement"></a>

以下 CREATE TABLE 语句演示不同数字数据类型的声明：

```
create table film (
film_id integer,
language_id smallint,
original_language_id smallint,
rental_duration smallint default 3,
rental_rate numeric(4,2) default 4.99,
length smallint,
replacement_cost real default 25.00);
```

## 尝试插入超出范围的整数
<a name="r_Examples_with_numeric_types201-attempt-to-insert-an-integer-that-is-out-of-range"></a>

以下示例尝试将值 33000 插入到 SMALLINT 列中。

```
insert into film(language_id) values(33000);
```

SMALLINT 的范围为 -32768 至 \$132767，因此 Amazon Redshift 将返回错误。

```
An error occurred when executing the SQL command:
insert into film(language_id) values(33000)

ERROR: smallint out of range [SQL State=22003]
```

## 将小数值插入到整数列中
<a name="r_Examples_with_numeric_types201-insert-a-decimal-value-into-an-integer-column"></a>

以下示例将小数值插入到 INT 列中。

```
insert into film(language_id) values(1.5);
```

插入此值，但会将其四舍五入为整数值 2。

## 插入由于小数位数四舍五入而成功的小数
<a name="r_Examples_with_numeric_types201-insert-a-decimal-that-succeeds-because-its-scale-is-rounded"></a>

以下示例将具有更高精度的小数值插入列中。

```
insert into film(rental_rate) values(35.512);
```

在此示例中，值 `35.51` 将插入列中。

## 尝试插入超出范围的小数值
<a name="r_Examples_with_numeric_types201-attempt-to-insert-a-decimal-value-that-is-out-of-range"></a>

在此示例中，值 `350.10` 超出范围。DECIMAL 列中值的位数等于此列的精度减去其小数位数（对于 RENTAL\$1RATE 列为 4 减去 2）。换言之，`DECIMAL(4,2)` 列所允许的范围为 `-99.99` 到 `99.99`。

```
insert into film(rental_rate) values (350.10);
ERROR:  numeric field overflow
DETAIL:  The absolute value is greater than or equal to 10^2 for field with precision 4, scale 2.
```

## 将精度可变的值插入到 REAL 列中
<a name="r_Examples_with_numeric_types201-insert-variable-precision-values-into-a-real-column"></a>

以下示例将精度可变的值插入到 REAL 列中。

```
insert into film(replacement_cost) values(1999999.99);

insert into film(replacement_cost) values(1999.99);

select replacement_cost from film;

+------------------+
| replacement_cost |
+------------------+
| 2000000          |
| 1999.99          |
+------------------+
```

值 `1999999.99` 将转换为 `2000000` 以满足 `REAL` 列的精度要求。值 `1999.99` 将按原样加载。

# 字符类型
<a name="r_Character_types"></a>

**Topics**
+ [存储和范围](#r_Character_types-storage-and-ranges)
+ [CHAR 或 CHARACTER](#r_Character_types-char-or-character)
+ [VARCHAR 或 CHARACTER VARYING](#r_Character_types-varchar-or-character-varying)
+ [NCHAR 和 NVARCHAR 类型](#r_Character_types-nchar-and-nvarchar-types)
+ [TEXT 和 BPCHAR 类型](#r_Character_types-text-and-bpchar-types)
+ [尾部空格的意义](#r_Character_types-significance-of-trailing-blanks)
+ [字符类型的示例](r_Examples_with_character_types.md)

字符数据类型包括 CHAR（字符）和 VARCHAR（字符变体）。

## 存储和范围
<a name="r_Character_types-storage-and-ranges"></a>

CHAR 和 VARCHAR 数据类型是按照字节而不是字符来定义的。CHAR 列只能包含单字节字符，因此 CHAR(10) 列可包含最大长度为 10 字节的字符串。VARCHAR 可包含多字节字符，并且每个字符最多可以有 4 个字节。例如，VARCHAR(12) 列可包含 12 个单字节字符、6 个双字节字符、4 个三字节字符或 3 个四字节字符。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Character_types.html)

**注意**  
CREATE TABLE 语法支持对字符数据类型使用 MAX 关键字。例如：  

```
create table test(col1 varchar(max));
```
对于 CHAR，MAX 将列宽度定义为 4096 字节。  
对于 VARCHAR，MAX 在 CREATE TABLE 语句中将列宽度定义为 65535 字节。对于内存中操作，VARCHAR(MAX) 最多可支持 16000000 字节。

## CHAR 或 CHARACTER
<a name="r_Character_types-char-or-character"></a>

使用 CHAR 或 CHARACTER 列存储固定长度字符串。这些字符串将使用空格填补，因此 CHAR(10) 列始终占用 10 字节的存储。

```
char(10)
```

 未指定长度的 CHAR 列将生成 CHAR(1) 列。

## VARCHAR 或 CHARACTER VARYING
<a name="r_Character_types-varchar-or-character-varying"></a>

使用 VARCHAR 或 CHARACTER VARYING 列存储具有固定限制的可变长度字符串。这些字符串不会使用空格填补，因此 VARCHAR(120) 列最多包含 120 个单字节字符、60 个双字节字符、40 个三字节字符或 30 个四字节字符。

```
varchar(120)
```

如果在 CREATE TABLE 语句中使用不带长度说明符的 VARCHAR 数据类型，则默认长度为 256。

[字符串函数](String_functions_header.md)现在支持最多 1600 万个字节。例如，CONCAT 函数之前的输出限制为 65535 个字节，现已提升至 1600 万个字节。

```
SELECT LEN(CONCAT(REPEAT('A', 5000000), REPEAT('B', 5000000))) AS total_length;

 total_length
--------------
     10000000
```

## NCHAR 和 NVARCHAR 类型
<a name="r_Character_types-nchar-and-nvarchar-types"></a>

您可使用 NCHAR 和 NVARCHAR 类型（也称为 NATIONAL CHARACTER 和 NATIONAL CHARACTER VARYING 类型）创建列。这些类型将分别转换为 CHAR 和 VARCHAR 类型，并且使用指定字节数量存储。

未指定长度的 NCHAR 列将转换为 CHAR(1) 列。

未指定长度的 NVARCHAR 列将转换为 VARCHAR(256) 列。

## TEXT 和 BPCHAR 类型
<a name="r_Character_types-text-and-bpchar-types"></a>

您可创建包含 TEXT 列的 Amazon Redshift 表，但此列将转换为接受最多包含 256 个字符的可变长度值的 VARCHAR(256) 列。

您可创建包含 BPCHAR（空格填补字符）类型的 Amazon Redshift 列，Amazon Redshift 会将此列转换为固定长度的 CHAR(256) 列。

## 尾部空格的意义
<a name="r_Character_types-significance-of-trailing-blanks"></a>

CHAR 和 VARCHAR 数据类型存储长度最多为 *n* 字节的字符串。尝试将更长的字符串存储到这些类型的列中将导致错误，除非额外的字符全为空格，这样字符串将截断至最大长度。如果字符串短于最大长度，CHAR 值将使用空格填补，但 VARCHAR 值将存储不带空格的字符串。

CHAR 值中的尾部空格始终无语义意义。当比较两个 CHAR 值时将忽视尾部空格，而不将其包含在 LENGTH 计算中，在将 CHAR 值转换为其他字符串类型时将删除尾部空格。

VARCHAR 和 CHAR 值中的尾部空格将在比较值时视为无语义意义。

长度计算将返回 VARCHAR 字符串的包含尾部空格在内的长度。尾部空格不会计入固定长度字符串的长度中。

# 字符类型的示例
<a name="r_Examples_with_character_types"></a>

## CREATE TABLE 语句
<a name="r_Examples_with_character_types-create-table-statement"></a>

以下 CREATE TABLE 语句演示 VARCHAR 和 CHAR 数据类型的使用：

```
create table address(
address_id integer,
address1 varchar(100),
address2 varchar(50),
district varchar(20),
city_name char(20),
state char(2),
postal_code char(5)
);
```

下列示例使用此表。

## 可变长度字符串中的尾部空格
<a name="r_Examples_with_character_types-trailing-blanks-in-variable-length-character-strings"></a>

由于 ADDRESS1 是 VARCHAR 列，插入的第二个地址中的尾部空格始终无语义意义。换言之，插入的这两个地址*匹配*。

```
insert into address(address1) values('9516 Magnolia Boulevard');

insert into address(address1) values('9516 Magnolia Boulevard  ');
```

```
select count(*) from address
where address1='9516 Magnolia Boulevard';

count
-------
2
(1 row)
```

如果 ADDRESS1 列是 CHAR 列并且插入了相同的值，则 COUNT(\$1) 查询会将字符串识别为相同并返回 `2`。

## LENGTH 函数的结果
<a name="r_Examples_with_character_types-results-of-the-length-function"></a>

LENGTH 函数识别 VARCHAR 列中的尾部空格：

```
select length(address1) from address;

length
--------
23
25
(2 rows)
```

CITY\$1NAME 列（是 CHAR 列）中的 `Augusta` 的值，不管输入字符串有任何尾部空格，始终返回 7 个字符的长度。

## 超出列长度的值
<a name="r_Examples_with_character_types-values-that-exceed-the-length-of-the-column"></a>

未截断字符串来匹配列的声明宽度：

```
insert into address(city_name) values('City of South San Francisco');
ERROR: value too long for type character(20)
```

解决此问题的一个办法是将此值强制转换为列的大小：

```
insert into address(city_name)
values('City of South San Francisco'::char(20));
```

在此示例中，字符串 (`City of South San Fr`) 的前 20 个字符将加载到列中。

# 日期时间类型
<a name="r_Datetime_types"></a>

**Topics**
+ [存储和范围](#r_Datetime_types-storage-and-ranges)
+ [DATE](#r_Datetime_types-date)
+ [TIME](#r_Datetime_types-time)
+ [TIMETZ](#r_Datetime_types-timetz)
+ [TIMESTAMP](#r_Datetime_types-timestamp)
+ [TIMESTAMPTZ](#r_Datetime_types-timestamptz)
+ [日期时间类型的示例](r_Examples_with_datetime_types.md)
+ [日期、时间和时间戳文本](r_Date_and_time_literals.md)
+ [间隔数据类型和文字](r_interval_data_types.md)

日期时间数据类型包括 DATE、TIME、TIMETZ、TIMESTAMP 和 TIMESTAMPTZ。

## 存储和范围
<a name="r_Datetime_types-storage-and-ranges"></a>

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Datetime_types.html)

## DATE
<a name="r_Datetime_types-date"></a>

使用 DATE 数据类型存储没有时间戳的简单日历日期。

## TIME
<a name="r_Datetime_types-time"></a>

TIME 是 TIME WITHOUT TIME ZONE 的别名。

使用 TIME 数据类型存储一天中的时间。

TIME 列存储小数秒的精度最高达到 6 位的值。

预设情况下，用户表和 Amazon Redshift 系统表中，TIME 值均为协调世界时 (UTC)。

## TIMETZ
<a name="r_Datetime_types-timetz"></a>

TIMETZ 是 TIME WITH TIME ZONE 的别名。

使用 TIMETZ 数据类型来存储带有时区的一天中的时间。

TIMETZ 列存储小数秒的精度最高达到 6 位的值。

预设情况下，用户表和 Amazon Redshift 系统表中的 TIME 值为 (UTC)。

## TIMESTAMP
<a name="r_Datetime_types-timestamp"></a>

TIMESTAMP 是 TIMESTAMP WITHOUT TIME ZONE 的别名。

使用 TIMESTAMP 数据类型存储包含日期和当日时间的完整时间戳值。

TIMESTAMP 列存储小数秒的精度最高达到 6 位的值。

如果将日期插入到 TIMESTAMP 列中，或插入具有部分时间戳值的日期，则值将隐式转换为完整时间戳值。此完整时间戳值具有缺少的小时、分钟和秒的默认值 (00)。输入字符串中的时区值被忽略。

预设情况下，用户表和 Amazon Redshift 系统表中的 TIMESTAMP 值为 (UTC)。

## TIMESTAMPTZ
<a name="r_Datetime_types-timestamptz"></a>

TIMESTAMPTZ 是 TIMESTAMP WITH TIME ZONE 的别名。

使用 TIMESTAMPTZ 数据类型输入包含日期、当日时间和时区的完整时间戳值。当输入值包含一个时区时，Amazon Redshift 使用时区将值转化为协 UTC 并存储 UTC 值。

要查看支持的时区名称的列表，请执行以下命令。

```
select pg_timezone_names();
```

 要查看支持的时区缩写的列表，请执行以下命令。

```
select pg_timezone_abbrevs();
```

您还可以在 [IANA 时区数据库](https://www.iana.org/time-zones)中找到有关时区的当前信息。

下表提供了时区格式的示例。


| 格式 | 示例 | 
| --- | --- | 
|  dd mon hh:mi:ss yyyy tz  |  17 Dec 07:37:16 1997 PST   | 
|  mm/dd/yyyy hh:mi:ss.ss tz  |  12/17/1997 07:37:16.00 PST  | 
|  mm/dd/yyyy hh:mi:ss.ss tz  |  12/17/1997 07:37:16.00 US/Pacific  | 
|  yyyy-mm-dd hh:mi:ss\$1/-tz  |  1997-12-17 07:37:16-08   | 
| dd.mm.yyyy hh:mi:ss tz |  17.12.1997 07:37:16.00 PST  | 

TIMESTAMPTZ 列存储小数秒的精度最高达到 6 位的值。

如果将日期插入到 TIMESTAMPTZ 列中，或插入具有部分时间戳的日期，则值将隐式转换为完整时间戳值。此完整时间戳值具有缺少的小时、分钟和秒的默认值 (00)。

TIMESTAMPTZ 值为用户表中的 UTC。

# 日期时间类型的示例
<a name="r_Examples_with_datetime_types"></a>

下面，您可以找到处理 Amazon Redshift 支持的日期时间类型的示例。

## 日期示例
<a name="r_Examples_with_datetime_types-date-examples"></a>

以下示例插入具有不同格式的日期并显示输出。

```
create table datetable (start_date date, end_date date);
```

```
insert into datetable values ('2008-06-01','2008-12-31');

insert into datetable values ('Jun 1,2008','20081231');
```

```
select * from datetable order by 1;

start_date |  end_date
-----------------------
2008-06-01 | 2008-12-31
2008-06-01 | 2008-12-31
```

如果您将时间戳值插入 DATE 列，时间部分会被忽略，只会加载日期。

## 时间示例
<a name="r_Examples_with_datetime_types-time-examples"></a>

以下示例插入具有不同格式的 TIME 和 TIMETZ 值并显示输出。

```
create table timetable (start_time time, end_time timetz);
```

```
insert into timetable values ('19:11:19','20:41:19 UTC');
insert into timetable values ('191119', '204119 UTC');
```

```
select * from timetable order by 1;
start_time |  end_time
------------------------
 19:11:19  | 20:41:19+00
 19:11:19  | 20:41:19+00
```

## 时间戳示例
<a name="r_Examples_with_datetime_types-timestamp-examples"></a>

如果您将日期插入到 TIMESTAMP 或 TIMESTAMPTZ 列中，时间将默认为午夜。例如，如果您插入文本 `20081231`，存储的值为 `2008-12-31 00:00:00`。

如要更改当前会话的时区，请使用 [SET](r_SET.md) 命令设置 [timezone](r_timezone_config.md) 配置参数。

下面的示例插入不同格式的时间戳并显示生成的表。

```
create table tstamp(timeofday timestamp, timeofdaytz timestamptz);

insert into tstamp values('Jun 1,2008  09:59:59', 'Jun 1,2008 09:59:59 EST' );
insert into tstamp values('Dec 31,2008 18:20','Dec 31,2008 18:20');
insert into tstamp values('Jun 1,2008  09:59:59 EST', 'Jun 1,2008 09:59:59');

SELECT * FROM tstamp;

+---------------------+------------------------+
|      timeofday      |      timeofdaytz       |
+---------------------+------------------------+
| 2008-06-01 09:59:59 | 2008-06-01 14:59:59+00 |
| 2008-12-31 18:20:00 | 2008-12-31 18:20:00+00 |
| 2008-06-01 09:59:59 | 2008-06-01 09:59:59+00 |
+---------------------+------------------------+
```

# 日期、时间和时间戳文本
<a name="r_Date_and_time_literals"></a>

以下是用于处理 Amazon Redshift 支持的日期、时间和时间戳文本的规则。

## 日期
<a name="r_Date_and_time_literals-dates"></a>

下列输入日期是您可加载到 Amazon Redshift 表中的 DATE 数据类型的文本日期值的所有有效示例。默认 `MDY DateStyle` 模式被认为是有效的。此模式意味着在字符串中，月份值将位于日期值之前，如 `1999-01-08` 和 `01/02/00`。

**注意**  
当您将日期或时间戳文本加载到表中时，这些文本必须用引号括起来。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Date_and_time_literals.html)

## Times
<a name="r_Date_and_time_literals-times"></a>

下列输入时间是您可加载到 Amazon Redshift 表中的 TIME 和 TIMETZ 数据类型的文本时间值的所有有效示例。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Date_and_time_literals.html)

## 时间戳
<a name="r_Date_and_time_literals-timestamps"></a>

下列输入时间戳是您可加载到 Amazon Redshift 表中的 TIMESTAMP 和 TIMESTAMPTZ 数据类型的文本时间值的所有有效示例。所有有效的日期文本可与下列时间文本组合。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Date_and_time_literals.html)

## 特殊日期时间值
<a name="r_Date_and_time_literals-special-datetime-values"></a>

下列特殊值可用作日期时间文本和日期函数的参数。它们需要单引号，并在查询处理期间转换为常规时间戳值。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Date_and_time_literals.html)

以下示例演示 `now` 和 `today` 如何与 DATEADD 函数结合使用。

```
select dateadd(day,1,'today');

date_add
---------------------
2009-11-17 00:00:00
(1 row)

select dateadd(day,1,'now');

date_add
----------------------------
2009-11-17 10:45:32.021394
(1 row)
```

# 间隔数据类型和文字
<a name="r_interval_data_types"></a>

您可以使用间隔数据类型以 `seconds`、`minutes`、`hours`、`days`、`months`、和 `years` 等为单位存储时间段。间隔数据类型和文字可用于日期时间计算，例如在日期和时间戳中添加间隔、对间隔求和以及从日期或时间戳中减去间隔。间隔文字可用作表中间隔数据类型列的输入值。

## 间隔数据类型的语法
<a name="r_interval_data_types-syntax"></a>

指定间隔数据类型以存储以年和月为单位的持续时间：

```
INTERVAL year_to_month_qualifier
```

指定间隔数据类型以存储以天、小时、分钟和秒为单位的持续时间：

```
INTERVAL day_to_second_qualifier [ (fractional_precision) ]
```

## 间隔文字的语法
<a name="r_interval_data_types-syntax-literal"></a>

指定间隔文字以定义以年和月为单位的持续时间：

```
INTERVAL quoted-string year_to_month_qualifier
```

指定间隔文字以定义以天、小时、分钟和秒为单位的持续时间：

```
INTERVAL quoted-string day_to_second_qualifier [ (fractional_precision) ]
```

## 参数
<a name="r_interval_data_types-arguments"></a>

 *引用字符串*   
指定正数值或负数值，以指定数量和日期时间单位作为输入字符串。如果*引用字符串*仅包含数字，Amazon Redshift 将根据 *year\$1to\$1month\$1qualifier* 或 *day\$1to\$1second\$1qualifier* 确定单位。例如，`'23' MONTH` 表示 `1 year 11 months`、`'-2' DAY` 表示 `-2 days 0 hours 0 minutes 0.0 seconds`，`'1-2' MONTH` 表示 `1 year 2 months`、`'13 day 1 hour 1 minute 1.123 seconds' SECOND` 表示 `13 days 1 hour 1 minute 1.123 seconds`。有关间隔输出格式的更多信息，请参阅[间隔样式](#r_interval_data_types-interval-styles)。

 *year\$1to\$1month\$1qualifier*   
指定间隔的范围。如果您使用限定词并创建时间单位小于限定词的间隔，Amazon Redshift 会截断并丢弃间隔中较小的部分。*year\$1to\$1month\$1qualifier* 的有效值为：  
+ `YEAR`
+ `MONTH`
+ `YEAR TO MONTH`

 *day\$1to\$1second\$1qualifier*   
指定间隔的范围。如果您使用限定词并创建时间单位小于限定词的间隔，Amazon Redshift 会截断并丢弃间隔中较小的部分。*day\$1to\$1second\$1qualifier* 的有效值为：  
+ `DAY`
+ `HOUR`
+ `MINUTE`
+ `SECOND`
+ `DAY TO HOUR`
+ `DAY TO MINUTE`
+ `DAY TO SECOND`
+ `HOUR TO MINUTE`
+ `HOUR TO SECOND`
+ `MINUTE TO SECOND`
INTERVAL 文字的输出会被截断为指定的最小 INTERVAL 分量。例如，在使用 MINUTE 限定词时，Amazon Redshift 会丢弃小于 MINUTE 的时间单位。  

```
select INTERVAL '1 day 1 hour 1 minute 1.123 seconds' MINUTE
```
结果值被截断为 `'1 day 01:01:00'`。

 *fractional\$1precision*   
可选参数，用于指定间隔中允许的小数位数。仅在间隔包含 SECOND 时，才应指定 *fractional\$1precision* 参数。例如，`SECOND(3)` 创建的间隔仅允许三个小数位，例如 1.234 秒。最大小数位数为六位。

会话配置 `interval_forbid_composite_literals` 确定在同时指定 YEAR TO MONTH 和 DAY TO SECOND 部分的间隔时是否返回错误。有关更多信息，请参阅 [interval\$1forbid\$1composite\$1literals](r_interval_forbid_composite_literals.md)。

## 间隔算术
<a name="r_interval_data_types-arithmetic"></a>

您可以将间隔值与其他日期时间值一起使用来执行算术运算。下表介绍了可用的运算以及每种运算产生的数据类型。

**注意**  
 能同时产生 `date` 和 `timestamp` 结果的运算是以等式中涉及的最小时间单位为基础的。例如，在将 `interval` 添加 `date` 时，如果是 YEAR TO MONTH 间隔，则结果为 `date`；如果是 DAY TO SECOND 间隔，则结果为时间戳。

第一操作数为 `interval` 的运算会对给定的第二操作数产生以下结果：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_interval_data_types.html)

第一操作数为 `date` 的运算会对给定的第二操作数产生以下结果：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_interval_data_types.html)

第一操作数为 `timestamp` 的运算会对给定的第二操作数产生以下结果：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_interval_data_types.html)

## 间隔样式
<a name="r_interval_data_types-interval-styles"></a>

您可以使用 SQL [SET](r_SET.md) 命令更改间隔值的输出显示格式。在 SQL 中使用间隔数据类型时，将其转换为文本可以查看预期的间隔风格，例如 `YEAR TO MONTH::text`。用于设置 `IntervalStyle` 值的可用值包括：
+ `postgres` – 遵循 PostgreSQL 风格。这是默认值。
+ `postgres_verbose` – 遵循 PostgreSQL 的详细风格。
+ `sql_standard` – 遵循 SQL 标准间隔文字风格。

以下命令将间隔风格设置为 `sql_standard`。

```
SET IntervalStyle to 'sql_standard';
```

**postgres 输出格式**

以下是 `postgres` 间隔风格的输出格式。每个数值都可以是负数。

```
'<numeric> <unit> [, <numeric> <unit> ...]'
```

```
select INTERVAL '1-2' YEAR TO MONTH::text 

varchar
---------------
1 year 2 mons
```

```
select INTERVAL '1 2:3:4.5678' DAY TO SECOND::text

varchar
------------------
1 day 02:03:04.5678
```

**postgres\$1verbose 输出格式**

postgres\$1verbose 语法与 postgres 类似，但是 postgres\$1verbose 输出还包含时间单位。

```
'[@] <numeric> <unit> [, <numeric> <unit> ...] [direction]'
```

```
select INTERVAL '1-2' YEAR TO MONTH::text 

varchar
-----------------
@ 1 year 2 mons
```

```
select INTERVAL '1 2:3:4.5678' DAY TO SECOND::text

varchar
---------------------------
@ 1 day 2 hours 3 mins 4.56 secs
```

**sql\$1standard 输出格式**

年至月间隔值的格式如下所示。在间隔之前指定负数表示间隔为负值，适用于整个间隔。

```
'[-]yy-mm'
```

日至秒值间隔的格式如下所示。

```
'[-]dd hh:mm:ss.ffffff'
```

```
SELECT INTERVAL '1-2' YEAR TO MONTH::text 
  
varchar   
-------
1-2
```

```
select INTERVAL '1 2:3:4.5678' DAY TO SECOND::text 

varchar
---------------
1 2:03:04.5678
```

## 间隔数据类型示例
<a name="r_interval_data_types-examples"></a>

以下示例演示如何将 INTERVAL 数据类型与表结合使用。

```
create table sample_intervals (y2m interval month, h2m interval hour to minute);
insert into sample_intervals values (interval '20' month, interval '2 days 1:1:1.123456' day to second);
select y2m::text, h2m::text from sample_intervals;


      y2m      |       h2m      
---------------+-----------------
 1 year 8 mons | 2 days 01:01:00
```

```
update sample_intervals set y2m = interval '2' year where y2m = interval '1-8' year to month;
select * from sample_intervals;

   y2m   |       h2m       
---------+-----------------
 2 years | 2 days 01:01:00
```

```
delete from sample_intervals where h2m = interval '2 1:1:0' day to second;
select * from sample_intervals;

 y2m | h2m 
-----+-----
```

## 间隔文字示例
<a name="r_interval_data_types_literals-examples"></a>

以下示例在间隔风格设置为 `postgres` 的情况下运行。

以下示例演示如何创建间隔为 1 年的 INTERVAL 文字。

```
select INTERVAL '1' YEAR 

intervaly2m
---------------
1 years 0 mons
```

如果您指定的*引用字符串*超过限定词，则剩余的时间单位将从间隔处截断。在以下示例中，13 个月的间隔变为 1 年零 1 个月，但由于使用 YEAR 限定词，剩余的 1 个月被排除在外。

```
select INTERVAL '13 months' YEAR

intervaly2m
---------------
1 years 0 mons
```

如果您使用的限定词小于间隔字符串，则会包括排除的单位。

```
select INTERVAL '13 months' MONTH

intervaly2m
---------------
1 years 1 mons
```

在间隔中指定精度会将小数位数截断为指定的精度。

```
select INTERVAL '1.234567' SECOND (3)

intervald2s
--------------------------------
0 days 0 hours 0 mins 1.235 secs
```

如果您未指定精度，Amazon Redshift 将使用最大精度 6。

```
select INTERVAL '1.23456789' SECOND

intervald2s
-----------------------------------
0 days 0 hours 0 mins 1.234567 secs
```

以下示例演示如何创建范围间隔。

```
select INTERVAL '2:2' MINUTE TO SECOND

intervald2s
------------------------------
0 days 0 hours 2 mins 2.0 secs
```

限定词决定了您要指定的单位。例如，尽管以下示例使用与前一个示例相同的“2:2”*引用字符串*，但 Amazon Redshift 仍会识别出它由于限定词而使用了不同的时间单位。

```
select INTERVAL '2:2' HOUR TO MINUTE

intervald2s
------------------------------
0 days 2 hours 2 mins 0.0 secs
```

还支持每个单位的缩写和复数。例如，`5s`、`5 second`、和 `5 seconds` 是等效间隔。支持的单位为年、月、小时、分钟和秒。

```
select INTERVAL '5s' SECOND

intervald2s
------------------------------
0 days 0 hours 0 mins 5.0 secs
```

```
select INTERVAL '5 HOURS' HOUR

intervald2s
------------------------------
0 days 5 hours 0 mins 0.0 secs
```

```
select INTERVAL '5 h' HOUR

intervald2s
------------------------------
0 days 5 hours 0 mins 0.0 secs
```

# 不带限定词语法的间隔文字示例
<a name="r_interval_literals"></a>

**注意**  
以下示例演示如何使用不带 `YEAR TO MONTH` 或 `DAY TO SECOND` 限定词的间隔文字。有关将推荐的间隔文字与限定词一起使用的信息，请参阅[间隔数据类型和文字](r_interval_data_types.md)。

使用间隔文本标识特定时间段（如 `12 hours` 或 `6 months`）。您可在涉及日期时间表达式的条件和计算中使用这些间隔文本。

 间隔文字用 INTERVAL 关键字与数量和支持的日期部分的组合来表示；例如 `INTERVAL '7 days'` 或 `INTERVAL '59 minutes'`。您可以将许多数量和单位连接在一起以形成更精确的间隔；例如：`INTERVAL '7 days, 3 hours, 59 minutes'`。还支持每个单位的缩写和复数；例如：`5 s`、`5 second` 和 `5 seconds` 是等效的间隔。

如果您未指定日期部分，则间隔值表示秒。您可指定数量值作为小数（例如：`0.5 days`）。

以下示例显示了具有不同间隔值的一系列计算。

以下选项向指定日期添加 1 秒。

```
select caldate + interval '1 second' as dateplus from date
where caldate='12-31-2008';
dateplus
---------------------
2008-12-31 00:00:01
(1 row)
```

以下选项向指定日期添加 1 分钟。

```
select caldate + interval '1 minute' as dateplus from date
where caldate='12-31-2008';
dateplus
---------------------
2008-12-31 00:01:00
(1 row)
```

以下选项向指定日期添加 3 小时 35 分钟。

```
select caldate + interval '3 hours, 35 minutes' as dateplus from date
where caldate='12-31-2008';
dateplus
---------------------
2008-12-31 03:35:00
(1 row)
```

以下选项向指定日期添加 52 周。

```
select caldate + interval '52 weeks' as dateplus from date
where caldate='12-31-2008';
dateplus
---------------------
2009-12-30 00:00:00
(1 row)
```

以下选项向指定日期添加 1 周、1 小时、1 分钟和 1 秒：

```
select caldate + interval '1w, 1h, 1m, 1s' as dateplus from date
where caldate='12-31-2008';
dateplus
---------------------
2009-01-07 01:01:01
(1 row)
```

以下选项向指定日期添加 12 小时（半天）。

```
select caldate + interval '0.5 days' as dateplus from date
where caldate='12-31-2008';
dateplus
---------------------
2008-12-31 12:00:00
(1 row)
```

以下计算将从 2023 年 2 月 15 日减去 4 个月，结果为 2022 年 10 月 15 日。

```
select date '2023-02-15' - interval '4 months';

?column?
---------------------
2022-10-15 00:00:00
```

以下计算将从 2023 年 3 月 31 日减去 4 个月，结果为 2022 年 11 月 30 日。计算时会考虑一个月中的天数。

```
select date '2023-03-31' - interval '4 months';

?column?
---------------------
2022-11-30 00:00:00
```

# 布尔值类型
<a name="r_Boolean_type"></a>

使用 BOOLEAN 数据类型在单字节列中存储 true 和 false 值。下表描述了布尔值的三种可能状态以及导致这些状态的文本值。不管输入字符串如何，Boolean 列将存储和输出“t”表示 true，“f”表示 false。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Boolean_type.html)

您可以使用 IS 比较将布尔值仅作为 WHERE 子句中的谓词进行检查。不能将 IS 比较与 SELECT 列表中的布尔值一起使用。

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

您可使用 BOOLEAN 列将每个客户的“有效/无效”状态存储在 CUSTOMER 表中。

```
create table customer(
custid int,
active_flag boolean default true);
```

```
insert into customer values(100, default);
```

```
select * from customer;
custid | active_flag
-------+--------------
   100 | t
```

如果未在 CREATE TABLE 语句中指定默认值（`true` 或 `false`），则插入默认值意味着插入 null。

在此示例中，查询从 USERS 表中选择喜欢运动而不喜欢电影院的用户：

```
select firstname, lastname, likesports, liketheatre
from users
where likesports is true and liketheatre is false
order by userid limit 10;

firstname |  lastname  | likesports | liketheatre
----------+------------+------------+-------------
Lars      | Ratliff    | t          | f
Mufutau   | Watkins    | t          | f
Scarlett  | Mayer      | t          | f
Shafira   | Glenn      | t          | f
Winifred  | Cherry     | t          | f
Chase     | Lamb       | t          | f
Liberty   | Ellison    | t          | f
Aladdin   | Haney      | t          | f
Tashya    | Michael    | t          | f
Lucian    | Montgomery | t          | f
(10 rows)
```

以下示例从 USERS 表中选择不清楚是否喜欢摇滚音乐的用户。

```
select firstname, lastname, likerock
from users
where likerock is unknown
order by userid limit 10;

firstname | lastname | likerock
----------+----------+----------
Rafael    | Taylor   |
Vladimir  | Humphrey |
Barry     | Roy      |
Tamekah   | Juarez   |
Mufutau   | Watkins  |
Naida     | Calderon |
Anika     | Huff     |
Bruce     | Beck     |
Mallory   | Farrell  |
Scarlett  | Mayer    |
(10 rows)
```

以下示例返回错误，因为它在 SELECT 列表中使用了 IS 比较。

```
select firstname, lastname, likerock is true as "check"
from users
order by userid limit 10;

[Amazon](500310) Invalid operation: Not implemented
```

以下示例成功，因为它在 SELECT 列表中使用了等于比较 ( = ) 而不是 IS 比较。

```
select firstname, lastname, likerock = true as "check"
from users
order by userid limit 10;

firstname | lastname  | check
----------+-----------+------
Rafael    | Taylor    |      
Vladimir  | Humphrey  |      
Lars      | Ratliff   | true 
Barry     | Roy       |      
Reagan    | Hodge     | true 
Victor    | Hernandez | true 
Tamekah   | Juarez    |      
Colton    | Roy       | false
Mufutau   | Watkins   |      
Naida     | Calderon  |
```

# HLLSKETCH 类型
<a name="r_HLLSKTECH_type"></a>

将 HLLSKETCH 数据类型用于 HyperLogLog 草图。Amazon Redshift 支持稀疏或密集的 HyperLogLog 草图表示。草图从稀疏开始，并在密集格式更有效地减少所使用的内存占用时切换为密集。

 在以下 JSON 格式导入、导出或打印草图时，Amazon Redshift 会自动转换稀疏的 HyperLogLog 草图。

```
{"logm":15,"sparse":{"indices":[4878,9559,14523],"values":[1,2,1]}}
```

Amazon Redshift 使用 Base64 格式的字符串表示形式来表示密集的 HyperLogLog 草图。

Amazon Redshift 使用以下 Base64 格式的字符串表示形式来表示密集的 HyperLogLog 草图。

```
"ABAABA..."
```

当在原始压缩中使用时，HLLSKETCH 对象的最大大小为 24580 个字节。

# SUPER 类型
<a name="r_SUPER_type"></a>

使用 SUPER 数据类型将半结构化数据或文档存储为值。尽管 Amazon Redshift 能够使用 VARCHAR 存储此类值，但我们建议改用 SUPER 数据类型。

半结构化数据不符合 SQL 数据库中使用的关系数据模型的刚性和表格结构。它包含引用数据中不同实体的标签。它们可以包含复杂的值，如数组、嵌套结构和其他与序列化格式（如 JSON）相关联的复杂结构。SUPER 数据类型是一组无 schema 数组和结构值，它们包含 Amazon Redshift 的所有其他标量类型。

SUPER 数据类型最高支持 16 MB 的单个 SUPER 对象的数据。有关 SUPER 数据类型的更多信息，包括在表中实现它的示例，请参阅[Amazon Redshift 中的半结构化数据](super-overview.md)。

Amazon Redshift 为使用 COPY 命令摄取以下半结构化数据格式提供了内置支持：
+  JSON 
+  ARRAY 
+  TEXT 
+  CSV 

只能从以下文件格式摄取大于 1MB 的 SUPER 对象：
+  Parquet 
+  JSON 
+  TEXT 
+  CSV 

SUPER 数据类型具有以下属性：
+ Amazon Redshift 标量值：
  + Null
  + 布尔值
  + 一个数字，如 smallint、整数、bigint、小数或浮点（如 float4 或 float8）
  + 字符串值，如 varchar 或 char
+ 一个复杂的值：
  + 一个值数组，包括标量或复数
  + 一个结构，也称为元组或对象，它是属性名称和值（标量或复数）的映射

这两种类型的复数值中的任何一种都包含它们自己的标量或复数值，而对规则性没有任何限制。

SUPER 数据类型的默认压缩编码为 ZSTD。有关压缩编码的更多信息，请参阅[压缩编码](c_Compression_encodings.md)。

SUPER 数据类型以无架构形式支持半结构化数据的持久性。虽然分层数据模型可以更改，但旧版本的数据可以共存在于同一个 SUPER 列中。

Amazon Redshift 使用 PartiQL 来实现数组和结构的导航。Amazon Redshift 还使用 PartiQL 语法遍历 SUPER 数组。有关更多信息，请参阅 [PartiQL：适用于 Amazon Redshift 的 SQL 兼容查询语言](super-partiql.md)。

Amazon Redshift 使用动态键入来处理无架构的 SUPER 数据，而无需在查询中使用数据类型之前声明数据类型。有关更多信息，请参阅 [动态键入](query-super.md#dynamic-typing-lax-processing)。

可以将动态数据掩蔽策略应用于 SUPER 类型列的路径上的标量值。有关动态数据掩蔽的更多信息，请参阅[动态数据掩蔽](t_ddm.md)。有关为 SUPER 数据类型使用动态数据掩蔽的信息，请参阅[对 SUPER 数据类型路径使用动态数据掩蔽](t_ddm-super.md)。

建议您在处理 SUPER 数据时将 `r_enable_case_sensitive_super_attribute` 配置选项设置为 true。有关更多信息，请参阅 [enable\$1case\$1sensitive\$1super\$1attribute](r_enable_case_sensitive_super_attribute.md)。

# VARBYTE 类型
<a name="r_VARBYTE_type"></a>

使用 VARBYTE、VARBINARY 或 BINARY VARYING 列存储具有固定限制的可变长度二进制值。

```
varbyte [ (n) ]
```

最大字节数（*n*）范围为 1 到 16,777,216。默认值为 64,000。

下面是一些你可能想使用 VARBYTE 数据类型的示例:
+ 在 VARBYTE 列上联接表。
+ 创建包含 VARBYTE 列的实体化视图。支持包含 VARBYTE 列的实体化视图的增量刷新。但是，除了 COUNT、MIN、MAX 和 GROUP BY 以外，VARBYTE 列上的聚合函数不支持增量刷新。

为确保所有字节都是可打印字符，Amazon Redshift 使用十六进制格式打印 VARBYTE 值。例如，以下 SQL 将十六进制字符串 `6162` 转换为二进制值。尽管返回值为二进制值，但结果将以十六进制形式 `6162` 打印。

```
select from_hex('6162');
                      
 from_hex
----------
 6162
```

Amazon Redshift 支持在 VARBYTE 和以下数据类型之间进行转换：
+ CHAR
+ VARCHAR
+ SMALLINT
+ INTEGER
+ BIGINT

使用 CHAR 和 VARCHAR 进行转换时，将采用 UTF-8 格式。有关 UTF-8 格式的更多信息，请参阅[TO\$1VARBYTE](r_TO_VARBYTE.md)。从 SMALLINT、INTEGER 和 BIGINT 进行转换时，原始数据类型的字节数将保持不变。对于 SMALLINT 是 2 个字节，INTEGER 是 4 个字节，BIGINT 是 8 个字节。

以下 SQL 语句将 VARCHAR 字符串转换为 VARBYTE。尽管返回值为二进制值，但结果将以十六进制形式 `616263` 打印。

```
select 'abc'::varbyte;
                      
 varbyte
---------
 616263
```

以下 SQL 语句将列中的 CHAR 值转换为 VARBYTE。此示例创建一个包含 CHAR(10) 列（c）的表，插入长度小于 10 的字符值。生成的转换使用空格字符（hex'20'）将结果填充到定义的列大小。尽管返回值是二进制值，但结果将以十六进制形式打印。

```
create table t (c char(10));
insert into t values ('aa'), ('abc');                 
select c::varbyte from t;
          c
----------------------
 61612020202020202020
 61626320202020202020
```

以下 SQL 语句将 SMALLINT 字符串转换为 VARBYTE。尽管返回值是二进制值，但结果将以十六进制形式 `0005` 打印，为 2 个字节或 4 个十六进制字符。

```
select 5::smallint::varbyte;
                  
 varbyte
---------
 0005
```

以下 SQL 语句将 INTEGER 转换为 VARBYTE。尽管返回值是二进制值，但结果将以十六进制形式 `00000005` 打印，为 4 个字节或 8 个十六进制字符。

```
select 5::int::varbyte;
                  
 varbyte
----------
 00000005
```

以下 SQL 语句将 BIGINT 转换为 VARBYTE。尽管返回值是二进制值，但结果将以十六进制形式 `0000000000000005` 打印，为 8 个字节或 16 个十六进制字符。

```
select 5::bigint::varbyte;
                  
     varbyte
------------------
 0000000000000005
```

支持 VARBYTE 数据类型的 Amazon Redshift 功能包括：
+ [VARBYTE 运算符](r_VARBYTE_OPERATORS.md)
+ [CONCAT](r_CONCAT.md)
+ [LEN](r_LEN.md)
+ [LENGTH 函数](r_LENGTH.md)
+ [OCTET\$1LENGTH](r_OCTET_LENGTH.md)
+ [SUBSTRING 函数](r_SUBSTRING.md)
+ [FROM\$1HEX](r_FROM_HEX.md)
+ [TO\$1HEX](r_TO_HEX.md)
+ [FROM\$1VARBYTE](r_FROM_VARBYTE.md)
+ [TO\$1VARBYTE](r_TO_VARBYTE.md)
+ [GETBIT](r_GETBIT.md)
+ [加载 VARBYTE 数据类型的列](copy-usage-varbyte.md)
+ [卸载 VARBYTE 数据类型的列](r_UNLOAD.md#unload-usage-notes)

## 将空间数据与 Amazon Redshift 一起使用时的限制
<a name="varbyte-limitations"></a>

以下是将 VARBYTE 数据类型与 Amazon Redshift 一起使用时的限制：
+ Amazon Redshift Spectrum 仅支持 Parquet 和 ORC 文件的 VARBYTE 数据类型。
+ Amazon Redshift 查询编辑器和 Amazon Redshift 查询编辑器 v2 尚未完全支持 VARBYTE 数据类型。因此，在处理 VARBYTE 表达式时，请使用不同的 SQL 客户端。

  作为使用查询编辑器的解决方法，如果您的数据长度等于或少于 1600 万个字节且内容是有效的 UTF-8，则您可以将 VARBYTE 值转换为 VARCHAR，例如：

  ```
  select to_varbyte('6162', 'hex')::varchar;
  ```
+ 您不能将 VARBYTE 数据类型与 Python 或 Lambda 用户定义的函数（UDF）结合使用。
+ 您不能从 VARBYTE 列创建 HLLSKETCH 列，也不能在 VARBYTE 列上使用近似去重统计。
+ 大于 1 MB 的 VARBYTE 值只能从以下文件格式中摄取：
  + Parquet
  + 文本
  + 逗号分隔值（CSV）

## 类型兼容性和转换
<a name="r_Type_conversion"></a>

您可以在下面找到关于类型转换规则和数据类型兼容性如何在 Amazon Redshift 中工作的讨论。

### 兼容性
<a name="r_Type_conversion-compatibility"></a>

 在各种数据库操作期间，将会出现数据类型匹配以及文本值和常量与数据类型的匹配，包括以下情况：
+ 表中的数据操控语言 (DML) 操作 
+ UNION、INTERSECT 和 EXCEPT 查询 
+ CASE 表达式 
+ 谓词（如 LIKE 和 IN）的计算 
+ 执行数据比较或提取的 SQL 函数的计算 
+ 数学运算符的比较 

这些运算的结果取决于类型转换规则和数据类型兼容性。*兼容性* 意味着并非总是需要特定值和特定数据类型的一对一匹配。由于一些数据类型是*兼容的*，因此可进行隐式转换或*强制转换*（更多信息请参阅[隐式转换类型](#implicit-conversion-types)）。如果数据类型不兼容，您有时可通过使用显式转换函数将值从一种数据类型转换为另一种数据类型。

### 一般兼容性和转换规则
<a name="r_Type_conversion-general-compatibility-and-conversion-rules"></a>

请注意下列兼容性和转换规则：
+ 一般来说，同属一种类型类别的数据类型（如不同的数字数据类型）是兼容的并且可隐式转换。

  例如，通过使用隐式转换，您可以将一个小数值插入整数列。小数进位为整数。或者，您可以从日期中提取一个数字值（如 `2008`）并将其插入到整数列中。
+ 数字数据类型强制实施将在您尝试插入超出范围的值时出现的溢出条件。例如，精度为 5 的小数值无法放入到精度定义为 4 的小数列中。绝不会截断整数或小数的整数部分；但是，小数的小数部分可以视情况进行向上或向下取整。但是，对于显示强制转换表中选定的值而得出的结果，不会进行四舍五入。
+ 不同类型的字符串是兼容的；包含单字节数据的 VARCHAR 列字符串和 CHAR 列字符串是兼容且可隐式转换的。包含多字节数据的 VARCHAR 字符串是不可兼容的。此外，如果字符串是适当的文本值，则您可以将字符串转换为日期、时间、时间戳或数字值；将忽略任何前导或尾部空格。反过来，您也可以将日期、时间、时间戳或数字值转换为固定长度或可变长度的字符串。
**注意**  
您要强制转换为数字类型的字符串必须包含数字的字符表示形式。例如，您可将字符串 `'1.0'` 或 `'5.9'` 强制转换为小数值，但无法将字符串 `'ABC'` 强制转换为任何数字类型。
+ 如果您将 DECIMAL 值与字符串进行比较，Amazon Redshift 会尝试将字符串转换为 DECIMAL 值。在将所有其他数值与字符串进行比较时，数值将转换为字符串。如果要强制进行相反的转换（例如，将字符串转换为正数，或者将 DECIMAL 值转换为字符串），请使用显式函数，例如 [CAST](r_CAST_function.md)。
+ 若要将 64 位 DECIMAL 或 NUMERIC 值转换为更高的精度，必须使用显式转换函数（如 CAST 或 CONVERT）。
+ 将 DATE 或 TIMESTAMP 转换为 TIMESTAMPTZ 时，或者将 TIME 转换为 TIMETZ 时，时区设置为当前会话时区。会话时区默认为 UTC。有关设置会话时区的更多信息，请参阅 [timezone](r_timezone_config.md)。
+ 与之类似，TIMESTAMPTZ 可根据当前会话时区转化为 DATE、TIME 或 TIMESTAMP。会话时区默认为 UTC。转换后，时区信息将被删除。
+ 使用当前会话时区（默认为 UTC）将代表有指定时区的时间戳的字符串转换为 TIMESTAMPTZ。使用当前会话时区（默认为 UTC）将代表有指定时区的时间的字符串转换为 TIMETZ。

### 隐式转换类型
<a name="implicit-conversion-types"></a>

有两种隐式转换类型：
+ 分配中的隐式转化，如 INSERT 或 UPDATE 命令中的设置值。
+ 表达式中的隐式转化，例如在 WHERE 子句中执行比较。

下表列出了在赋值或表达式中可隐式转换的数据类型。您还可使用显式转换函数执行这些转换。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/c_Supported_data_types.html)

**注意**  
在 TIMESTAMPTZ、TIMESTAMP、DATE、TIME、TIMETZ 或字符串之间的隐式转换使用当前会话时区。有关设置当前时间地区的信息，请参阅 [timezone](r_timezone_config.md)。  
除了彼此之外，GEOMETRY 和 GEOGRAPHY 数据类型不能隐式转换为任何其它数据类型。有关更多信息，请参阅 [CAST 函数](r_CAST_function.md)。  
无法将 VARBYTE 数据类型隐式转换为任何其它数据类型。有关更多信息，请参阅 [CAST 函数](r_CAST_function.md)。

### 对 SUPER 数据类型使用动态键入
<a name="r_dynamic_typing_SUPER"></a>

Amazon Redshift 使用动态键入处理无 schemal SUPER 数据，无需在查询中使用数据类型之前声明数据类型。动态键入使用导航到 SUPER 数据列的结果，而无需将其显式转换为 Amazon Redshift 类型。有关为 SUPER 数据类型使用动态键入的更多信息，请参阅[动态键入](query-super.md#dynamic-typing-lax-processing)。

您可以将 SUPER 值转换为其他数据类型或从其他数据类型进行转换，但存在一些例外情况。有关更多信息，请参阅 [限制](limitations-super.md)。

# 排序规则序列
<a name="c_collation_sequences"></a>

Amazon Redshift 不支持区域设置特定的或用户定义的排序规则序列。一般来说，如果缺少用于对数据值进行排序和比较的区域设置特定规则，则可能会影响任何上下文中的任何谓词的结果。例如，ORDER BY 表达式和函数（如 MIN、MAX 和 RANK）将根据数据的二进制 UTF8 顺序（不考虑区域设置特定字符）返回结果。

# 表达式
<a name="r_expressions"></a>

**Topics**
+ [简单表达式](#r_expressions-simple-expressions)
+ [复合表达式](r_compound_expressions.md)
+ [表达式列表](r_expression_lists.md)
+ [标量子查询](r_scalar_subqueries.md)
+ [函数表达式](r_function_expressions.md)

表达式是一个或多个值、运算符或计算结果为值的函数的组合。表达式的数据类型一般为其组成部分的数据类型。

## 简单表达式
<a name="r_expressions-simple-expressions"></a>

简单表达式是以下任一值：
+ 常量或文本值 
+ 列名称或列引用 
+ 标量函数 
+ 聚合（集合）函数 
+ 窗口函数 
+ 标量子查询 

简单表达式的示例包括：

```
5+12
dateid
sales.qtysold * 100
sqrt (4)
max (qtysold)
(select max (qtysold) from sales)
```

# 复合表达式
<a name="r_compound_expressions"></a>

复合表达式是由算术运算符联接的一系列简单表达式。复合表达式中使用的简单表达式必须返回数字值。

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

```
expression 
operator 
expression | (compound_expression)
```

## 参数
<a name="r_compound_expressions-arguments"></a>

 *expression*   
计算结果为值的简单表达式。

 *operator*   
 复合算术表达式可使用下列采用此优先顺序的运算符构造：  
+ ( )：用于控制计算顺序的圆括号
+ \$1、-：正号和负号/运算符
+  ^、\$1/、\$1\$1/：乘方、平方根、立方根
+ \$1、/、%：乘、除和取模运算符
+  @：绝对值
+ \$1、-：加和减
+ &、\$1、\$1、\$1、<<、>>：逻辑与、逻辑或、逻辑非、左移位、右移位运算符
+ \$1\$1：连接

 *(compound\$1expression)*   
复合表达式可以使用圆括号嵌套。

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

复合表达式的示例包括以下各项。

```
('SMITH' || 'JONES')
sum(x) / y
sqrt(256) * avg(column)
rank() over (order by qtysold) / 100
(select (pricepaid - commission) from sales where dateid = 1882) * (qtysold)
```

一些函数还可嵌套在其他函数中。例如，任何标量函数都可嵌套在另一标量函数中。以下示例返回一组数字的绝对值之和：

```
sum(abs(qtysold))
```

窗口函数无法用作聚合函数或其他窗口函数的参数。以下表达式将返回错误：

```
avg(rank() over (order by qtysold))
```

窗口函数可以包含一个嵌套的聚合函数。以下表达式对值集进行求和，然后为它们排序：

```
rank() over (order by sum(qtysold))
```

# 表达式列表
<a name="r_expression_lists"></a>

表达式列表是表达式的组合，可出现在成员条件和比较条件（WHERE 子句）以及 GROUP BY 子句中。

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

```
expression , expression , ... | (expression, expression, ...)
```

## 参数
<a name="r_expression_lists-arguments"></a>

 *expression*   
计算结果为值的简单表达式。表达式列表可包含一个或多个逗号分隔的表达式或一组或多组逗号分隔的表达式。如果存在多组表达式，则每组表达式必须包含数量相同的表达式，并且必须用圆括号隔开。每组中的表达式数量必须与条件中的运算符前的表达式的数量一致。

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

下面是条件中的表达式列表的示例：

```
(1, 5, 10)
('THESE', 'ARE', 'STRINGS')
(('one', 'two', 'three'), ('blue', 'yellow', 'green'))
```

每组中的表达式数量必须与语句的第一部分中的数量匹配：

```
select * from venue
where (venuecity, venuestate) in (('Miami', 'FL'), ('Tampa', 'FL'))
order by venueid;

venueid |        venuename        | venuecity | venuestate | venueseats
---------+-------------------------+-----------+------------+------------
28 | American Airlines Arena | Miami     | FL         |          0
54 | St. Pete Times Forum    | Tampa     | FL         |          0
91 | Raymond James Stadium   | Tampa     | FL         |      65647
(3 rows)
```

# 标量子查询
<a name="r_scalar_subqueries"></a>

标量子查询是圆括号中的常规 SELECT 查询，仅返回一个值：带有一个列的一行。执行此查询，返回值将在外部查询中使用。如果子查询返回零行，则子查询表达式的值为 null。如果它返回多行，则 Amazon Redshift 将返回错误。子查询可引用父查询中的变量，这将在子查询的任何一次调用中充当常量。

您可在需要表达式的大部分语句中使用标量子查询。标量子查询在下列情况下是无效表达式：
+ 作为表达式的默认值
+ 在 GROUP BY 和 HAVING 子句中

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

以下子查询计算 2008 年全年的每笔销售支付的平均价格，然后外部查询使用输出中的值来比较每个季度每笔销售的平均价格：

```
select qtr, avg(pricepaid) as avg_saleprice_per_qtr,
(select avg(pricepaid)
from sales join date on sales.dateid=date.dateid
where year = 2008) as avg_saleprice_yearly
from sales join date on sales.dateid=date.dateid
where year = 2008
group by qtr
order by qtr;
qtr  | avg_saleprice_per_qtr | avg_saleprice_yearly
-------+-----------------------+----------------------
1     |                647.64 |               642.28
2     |                646.86 |               642.28
3     |                636.79 |               642.28
4     |                638.26 |               642.28
(4 rows)
```

# 函数表达式
<a name="r_function_expressions"></a>

## 语法
<a name="r_function_expressions-syntax"></a>

任何内置函数均可用作表达式。函数调用的语法是函数的名称后跟用圆括号括起的参数列表。

```
function ( [expression [, expression...]] )
```

## 参数
<a name="r_function_expressions-arguments"></a>

 *函数*   
任何内置函数。有关一些示例函数，请参阅[SQL 函数参考](c_SQL_functions.md)。

 *expression*   
任何与函数预期的数据类型和参数计数匹配的表达式。

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

```
abs (variable)
select avg (qtysold + 3) from sales;
select dateadd (day,30,caldate) as plus30days from date;
```

# 条件
<a name="r_conditions"></a>

**Topics**
+ [语法](#r_conditions-synopsis)
+ [比较条件](r_comparison_condition.md)
+ [逻辑条件](r_logical_condition.md)
+ [模式匹配条件](pattern-matching-conditions.md)
+ [BETWEEN 范围条件](r_range_condition.md)
+ [Null 条件](r_null_condition.md)
+ [EXISTS 条件](r_exists_condition.md)
+ [IN 条件](r_in_condition.md)

 条件是包含一个或多个表达式和逻辑运算符的语句，计算结果为 true、false 或 unknown。条件有时也称为“谓词”。

**注意**  
所有字符串比较和 LIKE 模式匹配项均区分大小写。例如，“A”和“a”不匹配。但是，您可通过使用 ILIKE 谓词执行不区分大小写的模式匹配。

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

```
comparison_condition
| logical_condition
| range_condition
| pattern_matching_condition
| null_condition
| EXISTS_condition
| IN_condition
```

# 比较条件
<a name="r_comparison_condition"></a>

比较条件阐明两个值之间的逻辑关系。所有比较条件都是具有布尔值返回类型的二进制运算符。Amazon Redshift 支持下表中描述的比较运算符：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_comparison_condition.html)

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

= ANY \$1 SOME   
ANY 和 SOME 关键字与 *IN* 条件同义，当比较操作相对于可返回一个或多个值的子查询所返回的至少一个值为 true 时，将返回 true。对于 ANY 和 SOME，Amazon Redshift 仅支持 =（等于）条件。不支持不相等条件。  
不支持 ALL 谓词。

<> ALL  
ALL 关键字与 NOT IN（请参阅 [IN 条件](r_in_condition.md) 条件）同义并在表达式未包含在子查询的结果中时返回 true。对于 ALL，Amazon Redshift 仅支持 <> 或 \$1=（不等于）条件。不支持其他比较条件。

IS TRUE/FALSE/UNKNOWN  
非零值等于 TRUE，0 等于 FALSE，null 等于 UNKNOWN。请参阅[布尔值类型HLLSKETCH 类型](r_Boolean_type.md)数据类型。

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

下面是比较条件的一些简单示例：

```
a = 5
a < b
min(x) >= 5
qtysold = any (select qtysold from sales where dateid = 1882
```

以下查询返回 VENUE 表中座位数超过 10000 的场地：

```
select venueid, venuename, venueseats from venue
where venueseats > 10000
order by venueseats desc;

venueid |           venuename            | venueseats
---------+--------------------------------+------------
83 | FedExField                     |      91704
 6 | New York Giants Stadium        |      80242
79 | Arrowhead Stadium              |      79451
78 | INVESCO Field                  |      76125
69 | Dolphin Stadium                |      74916
67 | Ralph Wilson Stadium           |      73967
76 | Jacksonville Municipal Stadium |      73800
89 | Bank of America Stadium        |      73298
72 | Cleveland Browns Stadium       |      73200
86 | Lambeau Field                  |      72922
...
(57 rows)
```

此示例从 USERS 表中选择喜欢摇滚音乐的用户 (USERID)：

```
select userid from users where likerock = 't' order by 1 limit 5;

userid
--------
3
5
6
13
16
(5 rows)
```

此示例从 USERS 表中选择不清楚是否喜欢摇滚音乐的用户 (USERID)：

```
select firstname, lastname, likerock
from users
where likerock is unknown
order by userid limit 10;

firstname | lastname | likerock
----------+----------+----------
Rafael    | Taylor   |
Vladimir  | Humphrey |
Barry     | Roy      |
Tamekah   | Juarez   |
Mufutau   | Watkins  |
Naida     | Calderon |
Anika     | Huff     |
Bruce     | Beck     |
Mallory   | Farrell  |
Scarlett  | Mayer    |
(10 rows
```

## 具有 TIME 列的示例
<a name="r_comparison_condition-examples-time"></a>

下面的示例表 TIME\$1TEST 具有一个列 TIME\$1VAL（类型 TIME），其中插入了三个值。

```
select time_val from time_test;
            
time_val
---------------------
20:00:00
00:00:00.5550
00:58:00
```

以下示例从每个 timetz\$1val 中提取小时数。

```
select time_val from time_test where time_val < '3:00';
   time_val
---------------
 00:00:00.5550
 00:58:00
```

以下示例比较两种时间文本。

```
select time '18:25:33.123456' = time '18:25:33.123456';
 ?column?
----------
 t
```

## 具有 TIMETZ 列的示例
<a name="r_comparison_condition-examples-timetz"></a>

下面的示例表 TIMETZ\$1TEST 具有一个列 TIMETZ\$1VAL（类型 TIMETZ），其中插入了三个值。

```
select timetz_val from timetz_test;
            
timetz_val
------------------
04:00:00+00
00:00:00.5550+00
05:58:00+00
```

下面的示例仅选择小于 `3:00:00 UTC` 的 TIMETZ 值。将值转换为 UTC 后进行比较。

```
select timetz_val from timetz_test where timetz_val < '3:00:00 UTC';
                  
   timetz_val
---------------
 00:00:00.5550+00
```

以下示例比较两种 TIMETZ 文本。比较时忽略时区。

```
select time '18:25:33.123456 PST' < time '19:25:33.123456 EST';
                  
 ?column?
----------
 t
```

# 逻辑条件
<a name="r_logical_condition"></a>

逻辑条件组合两个条件的结果以生成一个结果。所有逻辑条件都是具有布尔值返回类型的二进制运算符。

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

```
expression
{ AND | OR }
expression
NOT expression
```

逻辑条件使用具有三个值的布尔逻辑，其中 null 值表示未知关系。下表描述逻辑条件的结果，其中 `E1` 和 `E2` 表示表达式：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_logical_condition.html)

NOT 运算符先于 AND 计算，而 AND 运算符先于 OR 运算符计算。使用的任何圆括号可优先于此默认计算顺序。

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

以下示例将返回 USERS 表中用户同时喜欢拉斯维加斯和运动的 USERID 和 USERNAME：

```
select userid, username from users
where likevegas = 1 and likesports = 1
order by userid;

userid | username
--------+----------
1 | JSG99FHE
67 | TWU10MZT
87 | DUF19VXU
92 | HYP36WEQ
109 | FPL38HZK
120 | DMJ24GUZ
123 | QZR22XGQ
130 | ZQC82ALK
133 | LBN45WCH
144 | UCX04JKN
165 | TEY68OEB
169 | AYQ83HGO
184 | TVX65AZX
...
(2128 rows)
```

下一个示例将返回 USERS 表中用户喜欢拉斯维加斯或运动或同时喜欢这二者的 USERID 和 USERNAME。此查询将返回上例中的所有输出以及只喜欢拉斯维加斯或运动的用户。

```
select userid, username from users
where likevegas = 1 or likesports = 1
order by userid;

userid | username
--------+----------
1 | JSG99FHE
2 | PGL08LJI
3 | IFT66TXU
5 | AEB55QTM
6 | NDQ15VBM
9 | MSD36KVR
10 | WKW41AIW
13 | QTF33MCG
15 | OWU78MTR
16 | ZMG93CDD
22 | RHT62AGI
27 | KOY02CVE
29 | HUH27PKK
...
(18968 rows)
```

以下查询使用圆括号将 `OR` 条件括起来以查找纽约或加利福尼亚演出过 Macbeth 的场地：

```
select distinct venuename, venuecity
from venue join event on venue.venueid=event.venueid
where (venuestate = 'NY' or venuestate = 'CA') and eventname='Macbeth'
order by 2,1;

venuename                |   venuecity
----------------------------------------+---------------
Geffen Playhouse                       | Los Angeles
Greek Theatre                          | Los Angeles
Royce Hall                             | Los Angeles
American Airlines Theatre              | New York City
August Wilson Theatre                  | New York City
Belasco Theatre                        | New York City
Bernard B. Jacobs Theatre              | New York City
...
```

删除此示例中的圆括号将更改逻辑和查询的结果。

以下示例使用 `NOT` 运算符：

```
select * from category
where not catid=1
order by 1;

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
...
```

以下示例使用一个 `NOT` 条件并后跟一个 `AND` 条件：

```
select * from category
where (not catid=1) and catgroup='Sports'
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
(4 rows)
```

# 模式匹配条件
<a name="pattern-matching-conditions"></a>

**Topics**
+ [LIKE](r_patternmatching_condition_like.md)
+ [SIMILAR TO](pattern-matching-conditions-similar-to.md)
+ [POSIX 运算符](pattern-matching-conditions-posix.md)

模式匹配运算符针对搜索条件表达式中指定的模式搜索字符串，然后根据是否找到匹配项来返回 true 或 false。Amazon Redshift 使用三种模式匹配方法：
+ LIKE 表达式

  LIKE 运算符将字符串表达式（如列名称）与使用通配符 `%`（百分比）和 `_`（下划线）的模式进行比较。LIKE 模式匹配始终涵盖整个字符串。LIKE 执行区分大小写的匹配，而 ILIKE 执行不区分大小写的匹配。
+ SIMILAR TO 正则表达式

  SIMILAR TO 运算符使用 SQL 标准正则表达式模式来匹配字符串表达式，该模式可包含一组模式匹配元字符，其中包括 LIKE 运算符支持的两个元字符。SIMILAR TO 匹配整个字符串并且执行区分大小写的匹配。
+ POSIX 样式的正则表达式 

  与 LIKE 和 SIMILAR TO 运算符相比，POSIX 正则表达式提供了更强大的模式匹配手段。POSIX 正则表达式模式可与字符串的任何部分匹配，并执行区分大小写的匹配。

使用 SIMILAR TO 或 POSIX 运算符的正则表达式匹配的计算成本高昂。我们建议尽可能使用 LIKE，尤其是在处理非常多的行时。例如，下列查询的功能相同，但使用 LIKE 的查询相比于使用正则表达式的查询的运行速度快若干倍：

```
select count(*) from event where eventname SIMILAR TO '%(Ring|Die)%'; 
select count(*) from event where eventname LIKE '%Ring%' OR eventname LIKE '%Die%';
```

# LIKE
<a name="r_patternmatching_condition_like"></a>

LIKE 运算符将字符串表达式（如列名称）与使用通配符 %（百分比）和 \$1（下划线）的模式进行比较。LIKE 模式匹配始终涵盖整个字符串。若要匹配字符串中任意位置的序列，模式必须以百分比符号开始和结尾。

LIKE 区分大小写；ILIKE 不区分大小写。

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

```
expression [ NOT ] LIKE | ILIKE pattern [ ESCAPE 'escape_char' ]
```

## 参数
<a name="r_patternmatching_condition_like-arguments"></a>

 *expression*   
有效的 UTF-8 字符表达式（如列名称）。

LIKE \$1 ILIKE   
LIKE 执行区分大小写的模式匹配。ILIKE 对单字节 UTF-8 (ASCII) 字符执行不区分大小写的模式匹配。要为多字节字符执行不区分大小写的模式匹配，请将 *expression* 上的 [LOWER](r_LOWER.md) 函数和带有 LIKE 函数的 *pattern* 一起使用。  
与比较谓词（例如 = 和 <>）相反，LIKE 和 ILIKE 谓词并不会隐式忽略尾随空格。要忽略尾随空格，请使用 RTRIM 或者将 CHAR 列显式强制转换为 VARCHAR。  
`~~` 运算符等同于 LIKE，而 `~~*` 等同于 ILIKE。此外，`!~~` 和 `!~~*` 运算符等同于 NOT LIKE 和 NOT ILIKE。

 *pattern*   
具有要匹配的模式的有效的 UTF-8 字符表达式。

 *escape\$1char*   
将对模式中的元字符进行转义的字符表达式。默认为两个反斜杠 ('\$1\$1')。

如果 *pattern* 不包含元字符，则模式仅表示字符串本身；在此情况下，LIKE 的行为与等于运算符相同。

其中一个字符表达式可以是 CHAR 或 VARCHAR 数据类型。如果它们不同，Amazon Redshift 会将 *pattern* 转换为 *expression* 的数据类型。

LIKE 支持下列模式匹配元字符：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_patternmatching_condition_like.html)

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

下表显示使用 LIKE 的模式匹配的示例：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_patternmatching_condition_like.html)

以下示例查找名称以“E”开头的所有城市：

```
select distinct city from users
where city like 'E%' order by city;
city
---------------
East Hartford
East Lansing
East Rutherford
East St. Louis
Easthampton
Easton
Eatontown
Eau Claire
...
```

以下示例查找姓中包含“ten”的用户：

```
select distinct lastname from users
where lastname like '%ten%' order by lastname;
lastname
-------------
Christensen
Wooten
...
```

以下示例演示如何匹配多个模式。

```
select distinct lastname from tickit.users
where lastname like 'Chris%' or lastname like '%Wooten' order by lastname;
lastname
-------------
Christensen
Christian
Wooten
...
```

以下示例查找第三和第四个字符为“ea”的城市。此命令使用 ILIKE 来演示不区分大小写的匹配：

```
select distinct city from users where city ilike '__EA%' order by city;
city
-------------
Brea
Clearwater
Great Falls
Ocean City
Olean
Wheaton
(6 rows)
```

以下示例使用默认转义字符串（\$1\$1）搜索包含“start\$1”（文本 `start` 后跟下划线 `_`)的字符串：

```
select tablename, "column" from pg_table_def 
where "column" like '%start\\_%'
limit 5;

     tablename     |    column
-------------------+---------------
 stl_s3client      | start_time
 stl_tr_conflict   | xact_start_ts
 stl_undone        | undo_start_ts
 stl_unload_log    | start_time
 stl_vacuum_detail | start_row
(5 rows)
```

以下示例指定“^”作为转义字符，然后使用该转义字符搜索包含“start\$1”（文本 `start` 后跟下划线 `_`)的字符串：

```
select tablename, "column" from pg_table_def 
where "column" like '%start^_%' escape '^' 
limit 5;

     tablename     |    column
-------------------+---------------
 stl_s3client      | start_time
 stl_tr_conflict   | xact_start_ts
 stl_undone        | undo_start_ts
 stl_unload_log    | start_time
 stl_vacuum_detail | start_row
(5 rows)
```

以下示例使用 `~~*` 运算符对以“Ag”开头的城市进行不区分大小写（ILIKE）的搜索。

```
select distinct city from users where city ~~* 'Ag%' order by city;
                   
city
------------
Agat	
Agawam	
Agoura Hills	
Aguadilla
```

# SIMILAR TO
<a name="pattern-matching-conditions-similar-to"></a>

SIMILAR TO 运算符使用 SQL 标准正则表达式模式来匹配字符串表达式（如列名称）。SQL 正则表达式可包含一组模式匹配元字符，包括 [LIKE](r_patternmatching_condition_like.md) 运算符支持的两个元字符。

仅当模式与整个字符串匹配时，SIMILAR TO 运算符才会返回 true，这与 POSIX 正则表达式的行为不同（其中的模式可与字符串的任何部分匹配）。

SIMILAR TO 执行区分大小写的匹配。

**注意**  
使用 SIMILAR TO 的正则表达式匹配的计算成本高昂。我们建议尽可能使用 LIKE，尤其是在处理非常多的行时。例如，下列查询的功能相同，但使用 LIKE 的查询相比于使用正则表达式的查询的运行速度快若干倍：  

```
select count(*) from event where eventname SIMILAR TO '%(Ring|Die)%'; 
select count(*) from event where eventname LIKE '%Ring%' OR eventname LIKE '%Die%';
```

## 语法
<a name="pattern-matching-conditions-similar-to-synopsis"></a>

```
expression [ NOT ] SIMILAR TO pattern [ ESCAPE 'escape_char' ]
```

## 参数
<a name="pattern-matching-conditions-similar-to-arguments"></a>

 *expression*   
有效的 UTF-8 字符表达式（如列名称）。

SIMILAR TO  
SIMILAR TO 对 *expression* 中的整个字符串执行区分大小写的模式匹配。

 *pattern*   
有效的 UTF-8 字符表达式，表示 SQL 标准正则表达式模式。

 *escape\$1char*   
将对模式中的元字符进行转义的字符表达式。默认为两个反斜杠 ('\$1\$1')。

如果 *pattern* 不包含元字符，则模式仅表示字符串本身。

其中一个字符表达式可以是 CHAR 或 VARCHAR 数据类型。如果它们不同，Amazon Redshift 会将 *pattern* 转换为 *expression* 的数据类型。

SIMILAR TO 支持下列模式匹配元字符：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/pattern-matching-conditions-similar-to.html)

## 示例
<a name="pattern-matching-conditions-similar-to-examples"></a>

下表显示了使用 SIMILAR TO 的模式匹配的示例：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/pattern-matching-conditions-similar-to.html)

以下示例查找名称包含“E”或“H”的城市：

```
SELECT DISTINCT city FROM users
WHERE city SIMILAR TO '%E%|%H%' ORDER BY city LIMIT 5;

      city
-----------------
 Agoura Hills
 Auburn Hills
 Benton Harbor
 Beverly Hills
 Chicago Heights
```

以下示例使用默认转义字符串（“`\\`”）搜索包含“`_`”的字符串：

```
SELECT tablename, "column" FROM pg_table_def
WHERE "column" SIMILAR TO '%start\\_%'
ORDER BY tablename, "column" LIMIT 5;

        tablename         |       column
--------------------------+---------------------
 stcs_abort_idle          | idle_start_time
 stcs_abort_idle          | txn_start_time
 stcs_analyze_compression | start_time
 stcs_auto_worker_levels  | start_level
 stcs_auto_worker_levels  | start_wlm_occupancy
```

以下示例指定“`^`”作为转义字符串，然后使用此转义字符串搜索包含“`_`”的字符串：

```
SELECT tablename, "column" FROM pg_table_def
WHERE "column" SIMILAR TO '%start^_%' ESCAPE '^'
ORDER BY tablename, "column" LIMIT 5;

        tablename         |       column
--------------------------+---------------------
 stcs_abort_idle          | idle_start_time
 stcs_abort_idle          | txn_start_time
 stcs_analyze_compression | start_time
 stcs_auto_worker_levels  | start_level
 stcs_auto_worker_levels  | start_wlm_occupancy
```

# POSIX 运算符
<a name="pattern-matching-conditions-posix"></a>

POSIX 正则表达式是指定匹配模式的字符序列。如果字符串是正则表达式描述的正则集的成员，则该字符串与正则表达式匹配。

与 [LIKE](r_patternmatching_condition_like.md) 和 [SIMILAR TO](pattern-matching-conditions-similar-to.md) 运算符相比，POSIX 正则表达式提供了更强大的模式匹配手段。POSIX 正则表达式模式可匹配字符串的任何部分，这与 SIMILAR TO 运算符不同，SIMILAR TO 运算符仅当其模式匹配整个字符串时才返回 true。

**注意**  
使用 POSIX 运算符的正则表达式匹配的计算成本高昂。我们建议尽可能使用 LIKE，尤其是在处理非常多的行时。例如，下列查询的功能相同，但使用 LIKE 的查询相比于使用正则表达式的查询的运行速度快若干倍：  

```
select count(*) from event where eventname ~ '.*(Ring|Die).*'; 
select count(*) from event where eventname LIKE '%Ring%' OR eventname LIKE '%Die%';
```

## 语法
<a name="pattern-matching-conditions-posix-synopsis"></a>

```
expression [ ! ] ~ pattern
```

## 参数
<a name="pattern-matching-conditions-posix-arguments"></a>

 *expression*   
有效的 UTF-8 字符表达式（如列名称）。

\$1  
求反运算符。请不要与正则表达式匹配。

\$1  
对 *expression* 的任何子字符串执行区分大小写的匹配。  
`~~` 是 [LIKE](r_patternmatching_condition_like.md) 的同义词。

 * 模式*   
表示正则表达式模式的字符串文本。

如果 *pattern* 不包含通配符，则模式仅表示字符串本身。

要搜索包含元字符的字符串（如“`. * | ? `”等），请使用两个反斜杠（“` \\`”）对字符进行转义。与 `SIMILAR TO` 和 `LIKE` 不同，POSIX 正则表达式语法不支持用户定义的转义字符。

其中一个字符表达式可以是 CHAR 或 VARCHAR 数据类型。如果它们不同，Amazon Redshift 会将 *pattern* 转换为 *expression* 的数据类型。

所有字符表达式都可以是 CHAR 或 VARCHAR 数据类型。如果表达式的数据类型不同，Amazon Redshift 会将其转换为 *expression* 的数据类型。

POSIX 模式匹配支持下列元字符：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/pattern-matching-conditions-posix.html)

Amazon Redshift 支持下列 POSIX 字符类。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/pattern-matching-conditions-posix.html)

 Amazon Redshift 在正则表达式中支持下列受 Perl 影响的运算符。使用两个反斜杠（“`\\`”）转义此运算符。  

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/pattern-matching-conditions-posix.html)

## 示例
<a name="pattern-matching-conditions-posix-synopsis-examples"></a>

下表显示了使用 POSIX 运算符的模式匹配的示例：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/pattern-matching-conditions-posix.html)

以下示例查找名称包含 `E` 或 `H` 的城市：

```
SELECT DISTINCT city FROM users
WHERE city ~ '.*E.*|.*H.*' ORDER BY city LIMIT 5;

      city
-----------------
 Agoura Hills
 Auburn Hills
 Benton Harbor
 Beverly Hills
 Chicago Heights
```

以下示例查找名称不包含 `E` 或 `H` 的城市：

```
SELECT DISTINCT city FROM users WHERE city !~ '.*E.*|.*H.*' ORDER BY city LIMIT 5;

      city
-----------------
 Aberdeen	
 Abilene	
 Ada	
 Agat	
 Agawam
```

以下示例使用转义字符串（“`\\`”）搜索包含句点的字符串。

```
SELECT venuename FROM venue
WHERE venuename ~ '.*\\..*'
ORDER BY venueid;

          venuename
------------------------------
 St. Pete Times Forum
 Jobing.com Arena
 Hubert H. Humphrey Metrodome
 U.S. Cellular Field
 Superpages.com Center
 E.J. Nutter Center
 Bernard B. Jacobs Theatre
 St. James Theatre
```

# BETWEEN 范围条件
<a name="r_range_condition"></a>

`BETWEEN` 条件使用关键字 `BETWEEN` 和 `AND` 测试表达式是否包含在某个值范围中。

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

```
expression [ NOT ] BETWEEN expression AND expression
```

表达式可以是数字、字符或日期时间数据类型，但它们必须是可兼容的。此范围包含起始值。

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

第一个示例计算有多少个事务登记了 2、3 或 4 票证的销售：

```
select count(*) from sales
where qtysold between 2 and 4;

count
--------
104021
(1 row)
```

范围条件包含开始和结束值。

```
select min(dateid), max(dateid) from sales
where dateid between 1900 and 1910;

min  | max 
-----+-----
1900 | 1910
```

范围条件中的第一个表达式必须是较小的值，第二个表达式必须是较大的值。在以下示例中，由于表达式的值，将始终返回零行：

```
select count(*) from sales
where qtysold between 4 and 2;

count
-------
0
(1 row)
```

但是，应用 NOT 修饰符将反转逻辑并生成所有行的计数：

```
select count(*) from sales
where qtysold not between 4 and 2;

count
--------
172456
(1 row)
```

以下查询将返回拥有 20000 到 50000 个座位的场馆的列表：

```
select venueid, venuename, venueseats from venue
where venueseats between 20000 and 50000
order by venueseats desc;

venueid |       venuename               | venueseats
---------+-------------------------------+------------
116 | Busch Stadium                 |      49660
106 | Rangers BallPark in Arlington |      49115
96 | Oriole Park at Camden Yards   |      48876
...
(22 rows)
```

以下示例演示了如何为日期值使用 BETWEEN：

```
select salesid, qtysold, pricepaid, commission, saletime 
from sales 
where eventid between 1000 and 2000 
   and saletime between '2008-01-01' and '2008-01-03'
order by saletime asc;

salesid | qtysold | pricepaid | commission |   saletime
--------+---------+-----------+------------+---------------
  65082 |       4 |       472 |       70.8 | 1/1/2008 06:06
 110917 |       1 |       337 |      50.55 | 1/1/2008 07:05
 112103 |       1 |       241 |      36.15 | 1/2/2008 03:15
 137882 |       3 |      1473 |     220.95 | 1/2/2008 05:18
  40331 |       2 |        58 |        8.7 | 1/2/2008 05:57
 110918 |       3 |      1011 |     151.65 | 1/2/2008 07:17
  96274 |       1 |       104 |       15.6 | 1/2/2008 07:18
 150499 |       3 |       135 |      20.25 | 1/2/2008 07:20
  68413 |       2 |       158 |       23.7 | 1/2/2008 08:12
```

请注意，尽管 BETWEEN 的范围包括在内，但日期默认具有 00:00:00 的时间值。示例查询中唯一有效的 1 月 3 日行是 saletime 为 `1/3/2008 00:00:00` 的行。

# Null 条件
<a name="r_null_condition"></a>

在缺少值或值未知时，null 条件测试是否存在 null。

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

```
expression IS [ NOT ] NULL
```

## 参数
<a name="r_null_condition-arguments"></a>

 *expression*   
任何表达式（如列）。

IS NULL   
当表达式的值为 null 时为 true；当表达式具有一个值时，为 false。

 IS NOT NULL   
当表达式的值为 null 时为 false；当表达式具有一个值时，为 true。

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

此示例指示 SALES 表的 QTYSOLD 字段中包含 null 的次数：

```
select count(*) from sales
where qtysold is null;
count
-------
0
(1 row)
```

# EXISTS 条件
<a name="r_exists_condition"></a>

EXISTS 条件测试子查询中是否存在行，并在子查询返回至少一个行时返回 true。如果指定 NOT，此条件将在子查询未返回任何行时返回 true。

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

```
[ NOT ] EXISTS (table_subquery)
```

## 参数
<a name="r_exists_condition-arguments"></a>

 EXISTS   
当 *table\$1subquery* 返回至少一行时，为 true。

NOT EXISTS   
当 *table\$1subquery* 未返回任何行时，为 true。

 *table\$1subquery*   
计算结果为包含一个或多个列和一个或多个行的表的子查询。

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

此示例针对具有任何类型的销售的日期返回所有日期标识符，一次返回一个日期：

```
select dateid from date
where exists (
select 1 from sales
where date.dateid = sales.dateid
)
order by dateid;

dateid
--------
1827
1828
1829
...
```

# IN 条件
<a name="r_in_condition"></a>

IN 条件测试一组值或一个子查询中的成员值。

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

```
expression [ NOT ] IN (expr_list | table_subquery)
```

## 参数
<a name="r_in_condition-arguments"></a>

 *expression*   
数字、字符或日期时间表达式，针对 *expr\$1list* 或 *table\$1subquery* 进行计算，必须是与列表或子查询的数据类型兼容的。

 *expr\$1list*   
一个或多个逗号分隔的表达式，或一组或多组逗号分隔的表达式（用括号限定）。

 *table\$1subquery*   
一个子查询，计算结果为具有一行或多行的表，但在其选择列表中限制为一列。

IN \$1 NOT IN   
如果表达式是表达式列表或查询的成员，则 IN 将返回 true。如果表达式不是成员，NOT IN 将返回 true。在下列情况下，IN 和 NOT IN 将返回 NULL 并且不会返回任何行：如果 *expression* 生成 null；或者，如果没有匹配的 *expr\$1list* 或 *table\$1subquery* 值并且至少一个比较行生成 null。

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

下列条件仅对列出的值有效：

```
qtysold in (2, 4, 5)
date.day in ('Mon', 'Tues')
date.month not in ('Oct', 'Nov', 'Dec')
```

## 优化大型 IN 列表
<a name="r_in_condition-optimization-for-large-in-lists"></a>

为了优化查询性能，包含 10 个以上的值的 IN 列表将在内部作为标量数组计算。少于 10 个值的 IN 列表将作为一系列 OR 谓词计算。SMALLINT、INTEGER、BIGINT、REAL、DOUBLE PRECISION、BOOLEAN、CHAR、VARCHAR、DATE、TIMESTAMP 和 TIMESTAMPTZ 数据类型均支持此优化。

查看查询的 EXPLAIN 输出以查看此优化的效果。例如：

```
explain select * from sales
QUERY PLAN
--------------------------------------------------------------------
XN Seq Scan on sales  (cost=0.00..6035.96 rows=86228 width=53)
Filter: (salesid = ANY ('{1,2,3,4,5,6,7,8,9,10,11}'::integer[]))
(2 rows)
```

# 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;
```

# SQL 函数参考
<a name="c_SQL_functions"></a>

**Topics**
+ [仅领导节点函数](c_SQL_functions_leader_node_only.md)
+ [聚合函数](c_Aggregate_Functions.md)
+ [数组函数](c_Array_Functions.md)
+ [按位聚合函数](c_bitwise_aggregate_functions.md)
+ [条件表达式](c_conditional_expressions.md)
+ [数据类型格式设置函数](r_Data_type_formatting.md)
+ [日期和时间函数](Date_functions_header.md)
+ [哈希函数](hash-functions.md)
+ [HyperLogLog 函数](hyperloglog-functions.md)
+ [JSON 函数](json-functions.md)
+ [机器学习函数。](ml-function.md)
+ [数学函数](Math_functions.md)
+ [对象函数](Object_Functions.md)
+ [空间函数](geospatial-functions.md)
+ [字符串函数](String_functions_header.md)
+ [SUPER 类型信息函数](c_Type_Info_Functions.md)
+ [VARBYTE 函数和运算符](varbyte-functions.md)
+ [窗口函数](c_Window_functions.md)
+ [系统管理函数](r_System_administration_functions.md)
+ [系统信息函数](r_System_information_functions.md)

Amazon Redshift 支持大量作为 SQL 标准的扩展的函数以及标准聚合函数、标量函数和窗口函数。

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

# 仅领导节点函数
<a name="c_SQL_functions_leader_node_only"></a>

一些 Amazon Redshift 查询是在计算节点上分发和运行的；而另一些查询仅在领导节点上运行。

当查询引用用户创建的表或系统表（具有 STL 或 STV 前缀的表和具有 SVL 或 SVV 前缀的系统视图）时，领导节点就会将 SQL 分发到计算节点。仅引用目录表（具有 PG 前缀的表（如 PG\$1TABLE\$1DEF））或不引用任何表的查询在领导节点上以独占方式运行。

部分 Amazon Redshift SQL 函数仅在领导节点上受支持，在计算节点上不受支持。使用领导节点函数的查询必须在领导节点上而不是计算节点上以独占方式执行，否则它将返回错误。

每个仅领导节点函数的文档均包含一个注释，指示该函数将在引用用户定义的表或 Amazon Redshift 系统表时返回错误。

有关更多信息，请参阅 [在领导节点上支持的 SQL 函数](c_sql-functions-leader-node.md)。

以下 SQL 函数为仅领导节点函数且在计算节点上不受支持：

系统信息函数
+ CURRENT\$1SCHEMA
+ CURRENT\$1SCHEMAS
+ HAS\$1DATABASE\$1PRIVILEGE
+ HAS\$1SCHEMA\$1PRIVILEGE
+ HAS\$1TABLE\$1PRIVILEGE

字符串函数
+ SUBSTR

数学函数
+ FACTORIAL
+  LOG 

以下仅领导节点函数已被弃用，不再受支持：

日期函数
+ AGE
+ CURRENT\$1TIME
+ CURRENT\$1TIMESTAMP
+ LOCALTIME
+ ISFINITE
+ NOW

字符串函数
+ GETBIT
+ GET\$1BYTE
+ SET\$1BIT
+ SET\$1BYTE
+ TO\$1ASCII

# 聚合函数
<a name="c_Aggregate_Functions"></a>

**Topics**
+ [ANY\$1VALUE 函数](r_ANY_VALUE.md)
+ [APPROXIMATE PERCENTILE\$1DISC 函数](r_APPROXIMATE_PERCENTILE_DISC.md)
+ [AVG 函数](r_AVG.md)
+ [COUNT 函数](r_COUNT.md)
+ [LISTAGG 函数](r_LISTAGG.md)
+ [MAX 函数](r_MAX.md)
+ [MEDIAN 函数](r_MEDIAN.md)
+ [MIN 函数](r_MIN.md)
+ [PERCENTILE\$1CONT 函数](r_PERCENTILE_CONT.md)
+ [STDDEV\$1SAMP 和 STDDEV\$1POP 函数](r_STDDEV_functions.md)
+ [SUM 函数](r_SUM.md)
+ [VAR\$1SAMP 和 VAR\$1POP 函数](r_VARIANCE_functions.md)

聚合函数从一组输入值计算单个结果值。

使用聚合函数的 SELECT 语句可以包含两个可选子句：GROUP BY 和 HAVING。这些子句的语法如下（使用 COUNT 函数作为示例）：

```
SELECT count (*) expression FROM table_reference
WHERE condition [GROUP BY expression ] [ HAVING condition]
```

GROUP BY 子句聚合结果并按指定的一列或多列中的唯一值对结果进行分组。HAVING 子句限制返回到满足某个特定聚合条件（如 count (\$1) > 1）的行中的结果。HAVING 子句的使用方式与 WHERE 用来基于列值限制行的方式相同。有关这些附加子句的示例，请参阅[COUNT](r_COUNT.md)。

聚合函数不接受嵌套聚合函数或窗口函数作为参数。

# ANY\$1VALUE 函数
<a name="r_ANY_VALUE"></a>

ANY\$1VALUE 函数以非确定方式返回输入表达式值中的任何值。如果输入表达式未导致任何行被返回，则此函数返回 `NULL`。如果输入表达式中有 `NULL` 值，则此函数也可以返回 `NULL`。如果输入包含 `NULL` 值并混有非 `NULL` 值，则可能会返回 `NULL`。如果所有值都是 `NULL`，则返回 `NULL`。如果没有符合条件的行，则返回 `NULL`。

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

```
ANY_VALUE( [ DISTINCT | ALL ] expression )
```

## 参数
<a name="r_ANY_VALUE-arguments"></a>

DISTINCT \$1 ALL  
指定 DISTINCT 或 ALL 以从输入表达式值中返回任何值。DISTINCT 参数没有任何效果，将被忽略。

 *expression*   
对其执行函数的目标列或表达式。*表达式*为以下数据类型之一：  
+ SMALLINT
+ INTEGER
+ BIGINT
+ DECIMAL
+ REAL
+ DOUBLE PRECISON
+ BOOLEAN
+ CHAR
+ VARCHAR
+ DATE
+ TIMESTAMP
+ TIMESTAMPTZ
+ TIME
+ TIMETZ
+ INTERVAL YEAR TO MONTH
+ INTERVAL DAY TO SECOND
+ VARBYTE
+ SUPER
+ HLLSKETCH
+ GEOMETRY
+ GEOGRAPHY

## 返回值
<a name="r_ANY_VALUE-returns"></a>

返回与 *expression* 相同的数据类型。

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

如果为列指定 ANY\$1VALUE 函数的语句也包含第二列引用，则第二列必须出现在 GROUP BY 子句中或包含在聚合函数中。

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

这些示例使用在《Amazon Redshift 入门指南》的[步骤 4：从 Amazon S3 中加载示例数据](https://docs.aws.amazon.com/redshift/latest/gsg/rs-gsg-create-sample-db.html)中创建的事件表。以下示例返回事件名称为 Eagles. 的任何日期 ID 的实例。

```
select any_value(dateid) as dateid, eventname from event where eventname ='Eagles' group by eventname;
```

以下是结果。

```
dateid | eventname
-------+---------------
 1878  | Eagles
```

以下示例返回事件名称为 Eagles 或 Cold War Kids 的任何日期 ID 的实例。

```
select any_value(dateid) as dateid, eventname from event where eventname in('Eagles', 'Cold War Kids') group by eventname;
```

以下是结果。

```
dateid | eventname
-------+---------------
 1922  | Cold War Kids
 1878  | Eagles
```

# APPROXIMATE PERCENTILE\$1DISC 函数
<a name="r_APPROXIMATE_PERCENTILE_DISC"></a>

APPROXIMATE PERCENTILE\$1DISC 是一种假定离散分布模型的逆分布函数。该函数具有一个百分比值和一个排序规范，并返回给定集合中的元素。近似值可以大幅加快函数运行速度，相对错误率较低，约为 0.5%。

如果给定*百分位数*值，APPROXIMATE PERCENTILE\$1DISC 会使用分位数摘要算法估计 ORDER BY 子句中的表达式的离散百分位数。APPROXIMATE PERCENTILE\$1DISC 返回的值具有最小的积累分布值（针对同一排序规范），该值大于或等于*百分位数*。

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

```
APPROXIMATE  PERCENTILE_DISC ( percentile )
WITHIN GROUP (ORDER BY expr)
```

## 参数
<a name="r_APPROXIMATE_PERCENTILE_DISC-arguments"></a>

 *percentile*   
介于 0 和 1 之间的数字常数。计算中将忽略 Null。

WITHIN GROUP ( ORDER BY *expr*)   
指定用于排序和计算百分比的数字或日期/时间值的子句。

## 返回值
<a name="r_APPROXIMATE_PERCENTILE_DISC-returns"></a>

与 WITHIN GROUP 子句中的 ORDER BY 表达式相同的数据类型。

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

如果 APPROXIMATE PERCENTILE\$1DISC 语句包括 GROUP BY 子句，结果集将受限。这一限制将根据节点类型和节点数量发生变化。如果超出限制，函数将失败并会返回以下错误。

```
GROUP BY limit for approximate percentile_disc exceeded.
```

如果您需要评估的组数量超出了限制，请考虑使用 [PERCENTILE\$1CONT 函数](r_PERCENTILE_CONT.md)。

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

以下示例返回销售数量、销售总额和排名前十位日期的第五十个百分位数。

```
select top 10 date.caldate,
count(totalprice), sum(totalprice),
approximate percentile_disc(0.5) 
within group (order by totalprice)
from listing
join date on listing.dateid = date.dateid
group by date.caldate
order by 3 desc;

caldate    | count | sum        | percentile_disc
-----------+-------+------------+----------------
2008-01-07 |   658 | 2081400.00 |         2020.00
2008-01-02 |   614 | 2064840.00 |         2178.00
2008-07-22 |   593 | 1994256.00 |         2214.00
2008-01-26 |   595 | 1993188.00 |         2272.00
2008-02-24 |   655 | 1975345.00 |         2070.00
2008-02-04 |   616 | 1972491.00 |         1995.00
2008-02-14 |   628 | 1971759.00 |         2184.00
2008-09-01 |   600 | 1944976.00 |         2100.00
2008-07-29 |   597 | 1944488.00 |         2106.00
2008-07-23 |   592 | 1943265.00 |         1974.00
```

# AVG 函数
<a name="r_AVG"></a>

 AVG 函数返回输入表达式值的平均值（算术平均值）。AVG 函数使用数值并忽略 NULL 值。

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

```
AVG ( [ DISTINCT | ALL ] expression )
```

## 参数
<a name="r_AVG-arguments"></a>

 *expression*   
对其执行函数的目标列或表达式。*表达式*为以下数据类型之一：  
+ SMALLINT
+ INTEGER
+ BIGINT
+ NUMERIC
+ DECIMAL
+ REAL
+ DOUBLE PRECISON
+ SUPER

DISTINCT \$1 ALL   
利用参数 DISTINCT，该函数可在计算平均值之前消除指定表达式中的所有重复值。利用参数 ALL，该函数可保留表达式中的所有重复值以计算平均值。ALL 是默认值。

## 数据类型
<a name="r_AVG-data-types"></a>

 AVG 函数支持的参数类型为 SMALLINT、INTEGER、BIGINT、NUMERIC、DECIMAL、REAL、DOUBLE PRECISION 和 SUPER。

AVG 函数支持的返回类型为：
+ 适用于任何整数类型参数的 BIGINT
+ 适用于浮点型参数的 DOUBLE PRECISION
+ 返回与任何其他参数类型的表达式相同的数据类型。

带有 NUMERIC 或 DECIMAL 参数的 AVG 函数结果的默认精度为 38。结果的小数位数与参数的小数位数相同。例如，DEC(5,2) 列的 AVG 返回 DEC(38,2) 数据类型。

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

从 SALES 表中查找每笔交易所售的平均产品数：

```
select avg(qtysold)from sales;

avg
-----
2
(1 row)
```

查找所有列表中列出的平均总价：

```
select avg(numtickets*priceperticket) as avg_total_price from listing;

avg_total_price
-----------------
3034.41
(1 row)
```

查找平均支付价格 (以降序顺序按月分组)：

```
select avg(pricepaid) as avg_price, month 
from sales, date
where sales.dateid = date.dateid
group by month
order by avg_price desc;

avg_price | month
-----------+-------
659.34 | MAR
655.06 | APR
645.82 | JAN
643.10 | MAY
642.72 | JUN
642.37 | SEP
640.72 | OCT
640.57 | DEC
635.34 | JUL
635.24 | FEB
634.24 | NOV
632.78 | AUG
(12 rows)
```

# COUNT 函数
<a name="r_COUNT"></a>

 COUNT 函数对由表达式定义的行计数。

COUNT 函数具有以下变体。
+ COUNT ( \$1 ) 对目标表中的所有行计数，无论它们是否包含 null 值。
+ COUNT ( *expression* ) 计算某个特定列或表达式中带非 NULL 值的行的数量。
+ COUNT ( DISTINCT *expression* ) 计算某个列或表达式中非重复的非 NULL 值的数量。
+ APPROXIMATE COUNT DISTINCT 估算某个列或表达式中非重复的非 NULL 值的数量。

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

```
COUNT( * | expression )
```

```
COUNT ( [ DISTINCT | ALL ] expression )
```

```
APPROXIMATE COUNT ( DISTINCT expression )
```

## 参数
<a name="r_COUNT-arguments"></a>

 *expression*   
对其执行函数的目标列或表达式。COUNT 函数支持所有参数数据类型。

DISTINCT \$1 ALL  
利用参数 DISTINCT，该函数可在执行计数之前消除指定表达式中的所有重复值。利用参数 ALL，该函数可保留表达式中的所有重复值以进行计数。ALL 是默认值。

APPROXIMATE  
与 APPROXIMATE 结合使用时，COUNT DISTINCT 函数使用 HyperLogLog 算法来估算某个列或表达式中非重复的非 NULL 值的数量。使用 APPROXIMATE 关键字的查询，运行速度会快得多，错误率相对较低，约为 2%。返回大量非重复值的查询可提供近似值，每个查询或组（如果有按子句划分的组）中有几百万或更多非重复值。对于较少数量（以千为单位）的非重复值，近似值计算可能慢于精确计数。APPROXIMATE 只能与 COUNT DISTINCT 结合使用。

## 返回类型
<a name="c_Supported_data_types_count"></a>

COUNT 函数返回 BIGINT。

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

对来自佛罗里达州的所有用户计数：

```
select count(*) from users where state='FL';

count
-------
510
```

对 EVENT 表中的所有事件名称计数：

```
select count(eventname) from event;

count
-------
8798
```

对 EVENT 表中的所有事件名称计数：

```
select count(all eventname) from event;

count
-------
8798
```

对 EVENT 表中的所有唯一场地 ID 计数：

```
select count(distinct venueid) as venues from event;

venues
--------
204
```

计算每个卖家列出 4 张以上门票出售的批次的次数。按卖家 ID 对结果进行分组：

```
select count(*), sellerid from listing 
where numtickets > 4
group by sellerid
order by 1 desc, 2;

count | sellerid
------+----------
12    |    6386
11    |    17304
11    |    20123
11    |    25428
...
```

以下示例比较 COUNT 和 APPROXIMATE COUNT 的返回值与执行时间。

```
select  count(distinct pricepaid) from sales;
              
count
-------
  4528


Time: 48.048 ms

               
select approximate count(distinct pricepaid) from sales;

count
-------
  4553


Time: 21.728 ms
```

# LISTAGG 函数
<a name="r_LISTAGG"></a>

对于查询中的每个组，LISTAGG 聚合函数根据 ORDER BY 表达式对该组的行进行排序，然后将值串联成一个字符串。

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

```
LISTAGG( [DISTINCT] aggregate_expression [, 'delimiter' ] ) 
[ WITHIN GROUP (ORDER BY order_list) ]
```

## 参数
<a name="r_LISTAGG-arguments"></a>

DISTINCT  
用于在串联之前消除指定表达式中重复值的子句。将忽略尾随空格。例如，字符串 `'a'` 和 `'a '` 视为重复项。LISTAGG 将使用遇到的第一个值。有关更多信息，请参阅 [尾部空格的意义](r_Character_types.md#r_Character_types-significance-of-trailing-blanks)。

 *aggregate\$1expression*   
 提供要聚合的值的任何有效表达式，如列名称。忽略 NULL 值和空字符串。

 *分隔符*   
用于分隔串联的值的字符串常数。默认值为 NULL。

 *WITHIN GROUP (ORDER BY order\$1list)*   
用于指定聚合值的排序顺序的子句。

## 返回值
<a name="r_LISTAGG-data-types"></a>

VARCHAR(MAX)。如果结果集大于最大 VARCHAR 大小，则 LISTAGG 返回以下错误：

```
Invalid operation: Result size exceeds LISTAGG limit
```

## 使用说明
<a name="r_LISTAGG-usage-notes"></a>
+ 如果语句包含多个使用 WITHIN GROUP 子句的 LISTAGG 函数，则每个 WITHIN GROUP 子句必须使用相同的 ORDER BY 值。

  例如，以下语句将返回错误。

  ```
  SELECT LISTAGG(sellerid) 
  WITHIN GROUP (ORDER BY dateid) AS sellers,
  LISTAGG(dateid) 
  WITHIN GROUP (ORDER BY sellerid) AS dates
  FROM sales;
  ```

  以下各条语句将成功运行。

  ```
  SELECT LISTAGG(sellerid) 
  WITHIN GROUP (ORDER BY dateid) AS sellers,
  LISTAGG(dateid) 
  WITHIN GROUP (ORDER BY dateid) AS dates
  FROM sales;
  
  SELECT LISTAGG(sellerid) 
  WITHIN GROUP (ORDER BY dateid) AS sellers,
  LISTAGG(dateid) AS dates
  FROM sales;
  ```
+ 您不能将 LISTAGG、PERCENTILE\$1CONT 和 MEDIAN 聚合函数与其它不同的聚合函数结合使用。

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

以下示例聚合卖家 ID（按卖家 ID 进行排序）。

```
SELECT LISTAGG(sellerid, ', ') 
WITHIN GROUP (ORDER BY sellerid) 
FROM sales
WHERE eventid = 4337;

listagg                                                                                                                                 
----------------------------------------------------------------------------------------------------------------------------------------
380, 380, 1178, 1178, 1178, 2731, 8117, 12905, 32043, 32043, 32043, 32432, 32432, 38669, 38750, 41498, 45676, 46324, 47188, 47188, 48294
```

以下示例使用 DISTINCT 返回唯一卖家 ID 的列表。

```
SELECT LISTAGG(DISTINCT sellerid, ', ') 
WITHIN GROUP (ORDER BY sellerid) 
FROM sales
WHERE eventid = 4337;

listagg                                                                                    
-------------------------------------------------------------------------------------------
380, 1178, 2731, 8117, 12905, 32043, 32432, 38669, 38750, 41498, 45676, 46324, 47188, 48294
```

以下示例按日期顺序聚合卖家 ID。

```
SELECT LISTAGG(sellerid, ', ')  
WITHIN GROUP (ORDER BY dateid) 
FROM sales
WHERE eventid = 4337;

   listagg
-----------------------------------------------------------------------------------------------------------------------------------------
 41498, 47188, 47188, 1178, 1178, 1178, 380, 45676, 46324, 48294, 32043, 32043, 32432, 12905, 8117, 38750, 2731, 32432, 32043, 380, 38669
```

以下示例返回 ID 为 660 的买家的销售日期的竖线分隔的列表。

```
SELECT LISTAGG(
    (SELECT caldate FROM date WHERE date.dateid=sales.dateid), ' | '    
)
WITHIN GROUP (ORDER BY sellerid DESC, salesid ASC)
FROM sales
WHERE buyerid = 660;

             listagg
-------------------------------------------------
2008-07-16 | 2008-07-09 | 2008-01-01 | 2008-10-26
```

以下示例返回买家 ID 660、661 和 662 的销售 ID 的逗号分隔列表。

```
SELECT buyerid, 
LISTAGG(salesid,', ')
WITHIN GROUP (ORDER BY salesid) AS sales_id
FROM sales
WHERE buyerid BETWEEN 660 AND 662
GROUP BY buyerid
ORDER BY buyerid;
            
buyerid |                sales_id
--------+-----------------------------------------------------
660     | 32872, 33095, 33514, 34548
661     | 19951, 20517, 21695, 21931
662     | 3318, 3823, 4215, 51980, 53202, 55908, 57832, 171603
```

# MAX 函数
<a name="r_MAX"></a>

 MAX 函数返回一组行中的最大值。可以使用 DISTINCT 或 ALL，但不会影响结果。

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

```
MAX ( [ DISTINCT | ALL ] expression )
```

## 参数
<a name="r_MAX-arguments"></a>

 *expression*   
对其执行函数的目标列或表达式。*表达式*为以下数据类型之一：  
+ SMALLINT
+ INTEGER
+ BIGINT
+ DECIMAL
+ REAL
+ DOUBLE PRECISON
+ CHAR
+ VARCHAR
+ DATE
+ TIMESTAMP
+ TIMESTAMPTZ
+ TIME
+ TIMETZ
+ VARBYTE
+ SUPER

DISTINCT \$1 ALL   
利用参数 DISTINCT，该函数可在计算最大值之前消除指定表达式中的所有重复值。利用参数 ALL，该函数可保留表达式中的所有重复值以计算最大值。ALL 是默认值。

## 数据类型
<a name="c_Supported_data_types_max"></a>

返回与 *expression* 相同的数据类型。MIN 函数的等效布尔值为 [BOOL\$1AND 函数](r_BOOL_AND.md)，MAX 函数的等效布尔值为 [BOOL\$1OR 函数](r_BOOL_OR.md)。

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

从所有销售中查找支付的最高价格：

```
select max(pricepaid) from sales;

max
----------
12624.00
(1 row)
```

从所有销售中查找每张门票的已支付最高价格：

```
select max(pricepaid/qtysold) as max_ticket_price
from sales;

max_ticket_price
-----------------
2500.00000000
(1 row)
```

# MEDIAN 函数
<a name="r_MEDIAN"></a>

计算一系列值的中值。此范围内的 `NULL` 值将被忽略。

MEDIAN 是一种假定连续分布模型的逆分布函数。

MEDIAN 是 [PERCENTILE\$1CONT](r_PERCENTILE_CONT.md) 的特殊情况。

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

```
MEDIAN(median_expression)
```

## 参数
<a name="r_MEDIAN-arguments"></a>

 *median\$1expression*   
对其执行函数的目标列或表达式。

## 数据类型
<a name="r_MEDIAN-data-types"></a>

返回类型由 *median\$1expression* 的数据类型确定。下表显示了每种 *median\$1expression* 数据类型的返回类型。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_MEDIAN.html)

## 使用说明
<a name="r_MEDIAN-data-type-usage-notes"></a>

如果 *median\$1expression* 参数是使用 38 位最大精度定义的 `DECIMAL` 数据类型，则 MEDIAN 可能将返回不准确的结果或错误。如果 MEDIAN 函数的返回值超过 38 位，则结果将截断以符合规范，这将导致精度降低。如果在插值期间，中间结果超出最大精度，则会发生数值溢出且函数会返回错误。要避免这些情况，建议使用具有较低精度的数据类型或将 *median\$1expression* 参数转换为较低精度。

如果语句包括对基于排序的聚合函数 (LISTAGG、PERCENTILE\$1CONT 或 MEDIAN) 的多个调用，则它们必须全都使用相同的 ORDER BY 值。请注意，MEDIAN 对表达式值应用隐式排序依据。

例如，以下语句将返回错误。

```
SELECT TOP 10 salesid, SUM(pricepaid), 
PERCENTILE_CONT(0.6) WITHIN GROUP(ORDER BY salesid),
MEDIAN(pricepaid)
FROM sales 
GROUP BY salesid, pricepaid;

An error occurred when executing the SQL command:
SELECT TOP 10 salesid, SUM(pricepaid), 
PERCENTILE_CONT(0.6) WITHIN GROUP(ORDER BY salesid),
MEDIAN(pricepaid)
FROM sales 
GROUP BY salesid, pricepaid;

ERROR: within group ORDER BY clauses for aggregate functions must be the same
```

以下语句将成功运行。

```
SELECT TOP 10 salesid, SUM(pricepaid), 
PERCENTILE_CONT(0.6) WITHIN GROUP(ORDER BY salesid),
MEDIAN(salesid)
FROM sales 
GROUP BY salesid, pricepaid;
```

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

以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

以下示例显示，MEDIAN 生成和 PERCENTILE\$1CONT(0.5) 相同的结果。

```
SELECT TOP 10 DISTINCT sellerid, qtysold, 
PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY qtysold),
MEDIAN(qtysold) 
FROM sales
GROUP BY sellerid, qtysold;

+----------+---------+-----------------+--------+
| sellerid | qtysold | percentile_cont | median |
+----------+---------+-----------------+--------+
|        2 |       2 |               2 |      2 |
|       26 |       1 |               1 |      1 |
|       33 |       1 |               1 |      1 |
|       38 |       1 |               1 |      1 |
|       43 |       1 |               1 |      1 |
|       48 |       2 |               2 |      2 |
|       48 |       3 |               3 |      3 |
|       77 |       4 |               4 |      4 |
|       85 |       4 |               4 |      4 |
|       95 |       2 |               2 |      2 |
+----------+---------+-----------------+--------+
```

以下示例查找每个 sellerid 的销售量中值。

```
SELECT sellerid, 
MEDIAN(qtysold)
FROM sales
GROUP BY sellerid
ORDER BY sellerid
LIMIT 10;

+----------+--------+
| sellerid | median |
+----------+--------+
|        1 |    1.5 |
|        2 |      2 |
|        3 |      2 |
|        4 |      2 |
|        5 |      1 |
|        6 |      1 |
|        7 |    1.5 |
|        8 |      1 |
|        9 |      4 |
|       12 |      2 |
+----------+--------+
```

要验证第一个 sellerid 的上一次查询的结果，请使用以下示例。

```
SELECT qtysold 
FROM sales 
WHERE sellerid=1;

+---------+
| qtysold |
+---------+
|       2 |
|       1 |
+---------+
```

# MIN 函数
<a name="r_MIN"></a>

 MIN 函数返回一组行中的最小值。可以使用 DISTINCT 或 ALL，但不会影响结果。

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

```
MIN ( [ DISTINCT | ALL ] expression )
```

## 参数
<a name="r_MIN-arguments"></a>

 *expression*   
对其执行函数的目标列或表达式。*表达式*为以下数据类型之一：  
+ SMALLINT
+ INTEGER
+ BIGINT
+ DECIMAL
+ REAL
+ DOUBLE PRECISON
+ CHAR
+ VARCHAR
+ DATE
+ TIMESTAMP
+ TIMESTAMPTZ
+ TIME
+ TIMETZ
+ VARBYTE
+ SUPER

DISTINCT \$1 ALL  
利用参数 DISTINCT，该函数可在计算最小值之前消除指定表达式中的所有重复值。利用参数 ALL，该函数可保留表达式中的所有重复值以计算最小值。ALL 是默认值。

## 数据类型
<a name="c_Supported_data_types_min"></a>

 返回与 *expression* 相同的数据类型。MIN 函数的等效布尔值为 [BOOL\$1AND 函数](r_BOOL_AND.md)，MAX 函数的等效布尔值为 [BOOL\$1OR 函数](r_BOOL_OR.md)。

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

从所有销售中查找支付的最低价格：

```
select min(pricepaid) from sales;

min
-------
20.00
(1 row)
```

从所有销售中查找每张门票的已支付最低价格：

```
select min(pricepaid/qtysold)as min_ticket_price
from sales;

min_ticket_price
------------------
20.00000000
(1 row)
```

# PERCENTILE\$1CONT 函数
<a name="r_PERCENTILE_CONT"></a>

PERCENTILE\$1CONT 是一种假定连续分布模型的逆分布函数。该函数具有一个百分比值和一个排序规范，并返回一个在有关排序规范的给定百分比值范围内的内插值。

PERCENTILE\$1CONT 在对值进行排序后计算值之间的线性内插。通过在聚合组中使用百分比值 `(P)` 和非 null 行数 `(N)`，该函数会在根据排序规范对行进行排序后计算行号。根据公式 `(RN)` 计算此行号 `RN = (1+ (P*(N-1))`。聚合函数的最终结果通过行号 `CRN = CEILING(RN)` 和 `FRN = FLOOR(RN)` 的行中的值之间的线性内插计算。

最终结果将如下所示。

如果 `(CRN = FRN = RN)`，则结果为 `(value of expression from row at RN)` 

否则，结果将如下所示：

`(CRN - RN) * (value of expression for row at FRN) + (RN - FRN) * (value of expression for row at CRN)`.

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

```
PERCENTILE_CONT(percentile)
WITHIN GROUP(ORDER BY expr)
```

## 参数
<a name="r_PERCENTILE_CONT-arguments"></a>

 *percentile*   
介于 0 和 1 之间的数值常数。计算中将忽略 `NULL` 值。

*\$1 expr*  
指定用于排序和计算百分比的数字或日期/时间值。

## 返回值
<a name="r_PERCENTILE_CONT-returns"></a>

返回类型由 WITHIN GROUP 子句中的 ORDER BY 表达式的数据类型决定。下表显示了每种个 ORDER BY 表达式数据类型的返回类型。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_PERCENTILE_CONT.html)

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

如果 ORDER BY 表达式是使用 38 位最大精度定义的 DECIMAL 数据类型，则 PERCENTILE\$1CONT 可能将返回不准确的结果或错误。如果 PERCENTILE\$1CONT 函数的返回值超过 38 位，结果将截断以符合规范，这将导致精度降低。如果在插值期间，中间结果超出最大精度，则会发生数值溢出且函数会返回错误。要避免这些情况，建议使用具有较低精度的数据类型或将 ORDER BY 表达式转换为较低精度。

如果语句包括对基于排序的聚合函数 (LISTAGG、PERCENTILE\$1CONT 或 MEDIAN) 的多个调用，则它们必须全都使用相同的 ORDER BY 值。请注意，MEDIAN 对表达式值应用隐式排序依据。

例如，以下语句将返回错误。

```
SELECT TOP 10 salesid, SUM(pricepaid), 
PERCENTILE_CONT(0.6) WITHIN GROUP(ORDER BY salesid),
MEDIAN(pricepaid)
FROM sales 
GROUP BY salesid, pricepaid;

An error occurred when executing the SQL command:
SELECT TOP 10 salesid, SUM(pricepaid), 
PERCENTILE_CONT(0.6) WITHIN GROUP(ORDER BY salesid),
MEDIAN(pricepaid)
FROM sales 
GROUP BY salesid, pricepaid;

ERROR: within group ORDER BY clauses for aggregate functions must be the same
```

以下语句将成功运行。

```
SELECT TOP 10 salesid, SUM(pricepaid), 
PERCENTILE_CONT(0.6) WITHIN GROUP(ORDER BY salesid),
MEDIAN(salesid)
FROM sales 
GROUP BY salesid, pricepaid;
```

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

以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

以下示例显示 PERCENTILE\$1CONT(0.5) 生成与 MEDIAN 相同的结果。

```
SELECT TOP 10 DISTINCT sellerid, qtysold, 
PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY qtysold),
MEDIAN(qtysold) 
FROM sales
GROUP BY sellerid, qtysold;

+----------+---------+-----------------+--------+
| sellerid | qtysold | percentile_cont | median |
+----------+---------+-----------------+--------+
|        2 |       2 |               2 |      2 |
|       26 |       1 |               1 |      1 |
|       33 |       1 |               1 |      1 |
|       38 |       1 |               1 |      1 |
|       43 |       1 |               1 |      1 |
|       48 |       2 |               2 |      2 |
|       48 |       3 |               3 |      3 |
|       77 |       4 |               4 |      4 |
|       85 |       4 |               4 |      4 |
|       95 |       2 |               2 |      2 |
+----------+---------+-----------------+--------+
```

以下示例为 SALES 表中每个 sellerid 的销售量找到 PERCENTILE\$1CONT(0.5) 和 PERCENTILE\$1CONT(0.75)。

```
SELECT sellerid, 
PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY qtysold) as pct_50,
PERCENTILE_CONT(0.75) WITHIN GROUP(ORDER BY qtysold) as pct_75
FROM sales
GROUP BY sellerid
ORDER BY sellerid
LIMIT 10;

+----------+--------+---------+
| sellerid | pct_50 | pct_75 |
+----------+--------+---------+
|        1 |    1.5 |    1.75 |
|        2 |      2 |    2.25 |
|        3 |      2 |       3 |
|        4 |      2 |       2 |
|        5 |      1 |     1.5 |
|        6 |      1 |       1 |
|        7 |    1.5 |    1.75 |
|        8 |      1 |       1 |
|        9 |      4 |       4 |
|       12 |      2 |    3.25 |
+----------+--------+---------+
```

要验证第一个 sellerid 的上一次查询的结果，请使用以下示例。

```
SELECT qtysold 
FROM sales 
WHERE sellerid=1;

+---------+
| qtysold |
+---------+
|       2 |
|       1 |
+---------+
```

# STDDEV\$1SAMP 和 STDDEV\$1POP 函数
<a name="r_STDDEV_functions"></a>

 STDDEV\$1SAMP 和 STDDEV\$1POP 函数返回一组数值（整数、小数或浮点）的样本标准差和总体标准差。STDDEV\$1SAMP 函数的结果等于同一组值的样本方差的平方根。

STDDEV\$1SAMP 和 STDDEV 是同一函数的同义词。

## 语法
<a name="r_STDDEV_functions-syntax"></a>

```
STDDEV_SAMP | STDDEV ( [ DISTINCT | ALL ] expression)
STDDEV_POP ( [ DISTINCT | ALL ] expression)
```

表达式必须具有整数、小数或浮点数据类型。无论表达式的数据类型如何，此函数的返回类型都是双精度数。

**注意**  
使用浮点算法计算标准偏差，其计算结果可能会稍微不准确。

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

当计算包含一个值的表达式的样本标准差（STDDEV 或 STDDEV\$1SAMP）时，函数的结果为 NULL 而不是 0。

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

以下查询返回 VENUE 表的 VENUESEATS 列中各值的平均数，后跟同一组值的样本标准差和总体标准差。VENUESEATS 是一个 INTEGER 列。结果的小数位数已减少至 2 位。

```
select avg(venueseats),
cast(stddev_samp(venueseats) as dec(14,2)) stddevsamp,
cast(stddev_pop(venueseats) as dec(14,2)) stddevpop
from venue;

avg  | stddevsamp | stddevpop
-------+------------+-----------
17503 |   27847.76 |  27773.20
(1 row)
```

以下查询返回 SALES 表中 COMMISSION 列的样本标准差。COMMISSION 是一个 DECIMAL 列。结果的小数位数已减少至 10 位。

```
select cast(stddev(commission) as dec(18,10))
from sales;

stddev
----------------
130.3912659086
(1 row)
```

以下查询将 COMMISSION 列的样本标准差转换为整数。

```
select cast(stddev(commission) as integer)
from sales;

stddev
--------
130
(1 row)
```

以下查询返回 COMMISSION 列的样本标准差和样本方差的平方根。这些计算的结果相同。

```
select
cast(stddev_samp(commission) as dec(18,10)) stddevsamp,
cast(sqrt(var_samp(commission)) as dec(18,10)) sqrtvarsamp
from sales;

stddevsamp   |  sqrtvarsamp
----------------+----------------
130.3912659086 | 130.3912659086
(1 row)
```

# SUM 函数
<a name="r_SUM"></a>

 SUM 函数返回输入列值或表达式值的和。SUM 函数使用数值并忽略 NULL 值。

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

```
SUM ( [ DISTINCT | ALL ] expression )
```

## 参数
<a name="r_SUM-arguments"></a>

 *expression*   
对其执行函数的目标列或表达式。*表达式*为以下数据类型之一：  
+ SMALLINT
+ INTEGER
+ BIGINT
+ NUMERIC
+ DECIMAL
+ REAL
+ DOUBLE PRECISON
+ SUPER

DISTINCT \$1 ALL   
利用参数 DISTINCT，该函数可在计算和之前消除指定表达式中的所有重复值。利用参数 ALL，该函数可保留表达式中的所有重复值以计算和。ALL 是默认值。

## 数据类型
<a name="c_Supported_data_types_sum"></a>

SUM 函数支持的参数类型为 SMALLINT、INTEGER、BIGINT、NUMERIC、DECIMAL、REAL、DOUBLE PRECISION 和 SUPER。

SUM 函数支持的返回类型为 
+ 适用于 BIGINT、SMALLINT 和 INTEGER 参数的 BIGINT
+ 适用于 NUMERIC 参数的 NUMERIC
+ 适用于浮点参数的 DOUBLE PRECISION
+ 返回与任何其他参数类型的表达式相同的数据类型。

带有 NUMERIC 或 DECIMAL 参数的 SUM 函数结果的默认精度为 38。结果的小数位数与参数的小数位数相同。例如，DEC(5,2) 列的 SUM 返回 DEC(38,2) 数据类型。

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

 从 SALES 表中查找所有已付佣金的和：

```
select sum(commission) from sales;

sum
-------------
16614814.65
(1 row)
```

查找佛罗里达州的所有场地的座位数：

```
select sum(venueseats) from venue
where venuestate = 'FL';

sum
--------
250411
(1 row)
```

查找 5 月份售出的座位数：

```
select sum(qtysold) from sales, date
where sales.dateid = date.dateid and date.month = 'MAY';

sum
-------
32291
(1 row)
```

# VAR\$1SAMP 和 VAR\$1POP 函数
<a name="r_VARIANCE_functions"></a>

 VAR\$1SAMP 和 VAR\$1POP 函数返回一组数值（整数、小数或浮点）的样本方差和总体方差。VAR\$1SAMP 函数的结果等于同一组值的样本标准差的平方。

VAR\$1SAMP 和 VARIANCE 是同一函数的同义词。

## 语法
<a name="r_VARIANCE_functions-syntax"></a>

```
VAR_SAMP | VARIANCE ( [ DISTINCT | ALL ] expression)
VAR_POP ( [ DISTINCT | ALL ] expression)
```

表达式必须具有整数、小数或浮点数据类型。无论表达式的数据类型如何，此函数的返回类型都是双精度数。

**注意**  
这些函数的结果可能跨数据仓库集群而异，具体取决于每个案例中集群的配置。

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

当计算包含一个值的表达式的样本方差（VARIANCE 或 VAR\$1SAMP）时，函数的结果为 NULL 而不是 0。

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

以下查询返回 LISTING 表中 NUMTICKETS 列的已取整样本方差和总体方差。

```
select avg(numtickets),
round(var_samp(numtickets)) varsamp,
round(var_pop(numtickets)) varpop
from listing;

avg | varsamp | varpop
-----+---------+--------
10 |      54 |     54
(1 row)
```

以下查询运行相同的计算但将结果转换为小数值。

```
select avg(numtickets),
cast(var_samp(numtickets) as dec(10,4)) varsamp,
cast(var_pop(numtickets) as dec(10,4)) varpop
from listing;

avg | varsamp | varpop
-----+---------+---------
10 | 53.6291 | 53.6288
(1 row)
```

# 数组函数
<a name="c_Array_Functions"></a>

下面，您可以找到 Amazon Redshift 支持用于访问和操作数组的 SQL 数组函数的描述。

**Topics**
+ [ARRAY 函数](r_array.md)
+ [ARRAY\$1CONCAT 函数](r_array_concat.md)
+ [ARRAY\$1CONTAINS 函数](array_contains.md)
+ [ARRAY\$1DISTINCT 函数](array_distinct.md)
+ [ARRAY\$1EXCEPT 函数](array_except.md)
+ [ARRAY\$1FLATTEN 函数](array_flatten.md)
+ [ARRAY\$1INTERSECTION 函数](array_intersection.md)
+ [ARRAY\$1POSITION 函数](array_position.md)
+ [ARRAY\$1POSITIONS 函数](array_positions.md)
+ [ARRAY\$1SORT 函数](array_sort.md)
+ [ARRAY\$1UNION 函数](array_union.md)
+ [ARRAYS\$1OVERLAP 函数](arrays_overlap.md)
+ [GET\$1ARRAY\$1LENGTH 函数](get_array_length.md)
+ [SPLIT\$1TO\$1ARRAY 函数](split_to_array.md)
+ [SUBARRAY 函数](r_subarray.md)

# ARRAY 函数
<a name="r_array"></a>

创建 SUPER 数据类型的数组。

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

```
ARRAY( [ expr1 ] [, expr2 [, ... ]] )
```

## 参数
<a name="r_array-argument"></a>

 *expr1、expr2*   
除日期和时间类型以外的任何 Amazon Redshift 数据类型的表达式，因为 Amazon Redshift 不会将日期和时间类型转换为 SUPER 数据类型。参数不需要为相同的数据类型。

## 返回类型
<a name="r_array-return-type"></a>

ARRAY 函数返回 SUPER 数据类型。

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

以下示例显示了一个数值数组和一个不同数据类型的数组。

```
--an array of numeric values
select ARRAY(1,50,null,100);
      array
------------------
 [1,50,null,100]
(1 row)

--an array of different data types
select ARRAY(1,'abc',true,3.14);
        array
-----------------------
 [1,"abc",true,3.14]
(1 row)
```

## 另请参阅
<a name="r_array-see-also"></a>
+ [ARRAY\$1CONCAT 函数](r_array_concat.md)
+ [SPLIT\$1TO\$1ARRAY 函数](split_to_array.md)
+ [ARRAY\$1FLATTEN 函数](array_flatten.md)

# ARRAY\$1CONCAT 函数
<a name="r_array_concat"></a>

连接两个数组来创建一个数组，该数组包含第一个数组中的所有元素，然后包含第二个数组中的所有元素。这两个参数必须是有效的 SUPER 数组。

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

```
ARRAY_CONCAT( array1, array2 )
```

## 参数
<a name="r_array_concat-argument-arguments"></a>

 *array1*  
指定要连接的两个数组中的第一个数组的值。

 *array2*  
指定要连接的两个数组中的第二个数组的值。

## 返回类型
<a name="r_array_concat-return-type"></a>

ARRAY\$1CONCAT 函数返回一个 SUPER 数据值。

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

以下示例显示了相同类型的两个数组的连接以及两个不同类型的数组的连接。

```
-- concatenating two arrays 
SELECT ARRAY_CONCAT(ARRAY(10001,10002),ARRAY(10003,10004));
              array_concat
------------------------------------
 [10001,10002,10003,10004]
(1 row)

-- concatenating two arrays of different types 
SELECT ARRAY_CONCAT(ARRAY(10001,10002),ARRAY('ab','cd'));
          array_concat
------------------------------
 [10001,10002,"ab","cd"]
(1 row)
```

## 另请参阅
<a name="r_array_concat-see-also"></a>
+ [ARRAY\$1UNION 函数](array_union.md)
+ [ARRAY\$1FLATTEN 函数](array_flatten.md)
+ [SPLIT\$1TO\$1ARRAY 函数](split_to_array.md)
+ [ARRAY\$1DISTINCT 函数](array_distinct.md)

# ARRAY\$1CONTAINS 函数
<a name="array_contains"></a>

检查数组是否包含给定值，如果找到，则返回 TRUE。

## 语法
<a name="array_contains-syntax"></a>

```
ARRAY_CONTAINS( array, value [, null_match] )
```

## 参数
<a name="array_contains-arguments"></a>

 *array*   
一个 SUPER 表达式，用于指定要在其中进行搜索的数组。

 *值*   
一个值，用于指定要搜索的元素。

 *null\$1match*   
一个布尔值，用于指定如何处理 NULL 值：  
+ *null\$1match* = FALSE：搜索 NULL 将返回 NULL。如果数组包含 NULL 值，但找不到与非 NULL 搜索值匹配的值，则返回 NULL。
+ *null\$1match* = TRUE：NULL 被视为有效、可搜索的元素。如果数组包含 NULL 值，但找不到与非 NULL 搜索值匹配的值，则返回 FALSE。
默认值为 TRUE。  
也可以通过配置选项指定默认的 NULL 处理：  

```
-- same as null_match = TRUE
SET default_array_search_null_handling to TRUE;
```

## 返回类型
<a name="array_contains-return-type"></a>

ARRAY\$1CONTAINS 函数返回 BOOLEAN 类型。

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

以下示例显示 ARRAY\$1CONTAINS 函数。

```
SELECT ARRAY_CONTAINS(ARRAY('red', 'green'), 'red');
array_contains
----------------
 t
(1 row)
```

以下示例显示 *null\$1match* 设置为 TRUE 时的函数行为。

```
SET default_array_search_null_handling to TRUE;

-- NULL search is enabled
SELECT ARRAY_CONTAINS(ARRAY('red', NULL, 'green'), NULL);
array_contains
----------------
 t
(1 row)

-- The array can contain NULLs
SELECT ARRAY_CONTAINS(ARRAY('red', NULL, 'green'), 'blue', TRUE);
array_contains
----------------
 f
(1 row)
```

以下示例显示 *null\$1match* 设置为 FALSE 时的函数行为。请注意，在函数中指定 *null\$1match* 行为将覆盖默认配置设置。

```
-- same as null_match = TRUE
SET default_array_search_null_handling to TRUE;

-- NULL search is disabled. The default behavior is overridden
SELECT ARRAY_CONTAINS(ARRAY('red', 'green'), NULL, FALSE);
array_contains
----------------
 
(1 row)

-- same as null_match = FALSE
SET default_array_search_null_handling to FALSE;

-- The array contains NULL and a match is found
SELECT ARRAY_CONTAINS(ARRAY('red', NULL, 'green'), 'green');
array_contains
----------------
 t
(1 row)

-- The array contains NULL but no match is found
SELECT ARRAY_CONTAINS(ARRAY('red', NULL, 'green'), 'blue');
array_contains
----------------
 
(1 row)
```

## 另请参阅
<a name="array_contains-see-also"></a>
+ [ARRAY\$1POSITION 函数](array_position.md)
+ [ARRAY\$1POSITIONS 函数](array_positions.md)
+ [ARRAYS\$1OVERLAP 函数](arrays_overlap.md)

# ARRAY\$1DISTINCT 函数
<a name="array_distinct"></a>

创建一个新数组，其中仅包含输入数组中具有唯一性的元素，而移除所有重复项。输出数组中元素的顺序不能保证与输入顺序匹配。NULL 值被视为有效元素；如果输入数组中存在多个 NULL，则输出中只会出现一个 NULL。

## 语法
<a name="array_distinct-syntax"></a>

```
ARRAY_DISTINCT( array )
```

## 参数
<a name="array_distinct-arguments"></a>

 *array*   
一个用于指定数组的 SUPER 表达式。

## 返回类型
<a name="array_distinct-return-type"></a>

ARRAY\$1DISTINCT 函数返回 SUPER 类型。

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

以下示例显示 ARRAY\$1DISTINCT 函数。

```
SELECT ARRAY_DISTINCT(ARRAY(1, 1, 'a', 'a', NULL, NULL));
 array_distinct 
----------------
 [1,"a",null]
(1 row)

SELECT ARRAY_DISTINCT(ARRAY_CONCAT(ARRAY(1,2,3,3),ARRAY(2,3,4,4)));
 array_distinct 
----------------
 [1,2,3,4]
(1 row)
```

## 另请参阅
<a name="array_distinct-see-also"></a>
+ [ARRAY\$1UNION 函数](array_union.md)
+ [ARRAY\$1SORT 函数](array_sort.md)
+ [ARRAY\$1EXCEPT 函数](array_except.md)
+ [ARRAY\$1INTERSECTION 函数](array_intersection.md)

# ARRAY\$1EXCEPT 函数
<a name="array_except"></a>

通过保留第一个数组中不存在于第二个数组中的元素，返回两个数组之间的差异。该函数是 NULL 安全的，这意味着它将 NULL 视为已知对象。

## 语法
<a name="array_except-syntax"></a>

```
ARRAY_EXCEPT( array1, array2 [, distinct] )
```

## 参数
<a name="array_except-arguments"></a>

 *array1*   
一个用于指定第一个数组的 SUPER 表达式。

 *array2*   
一个用于指定第二个数组的 SUPER 表达式。

 *区分*   
一个布尔值，用于指定是否只返回不同的元素：  
+ *distinct* = FALSE：多集语义适用。第一个数组中元素的每次出现都与第二个数组中的出现进行匹配。如果第一个数组中某个元素的出现次数多于第二个数组，则多余的出现次数将保留在结果中。
+ *distinct* = TRUE：集合语义适用。两个数组都被视为集合，忽略重复的元素。如果第一个数组中的元素存在于第二个数组中的任何地方，则无论出现次数如何，元素都将被移除。
默认值为 FALSE。

## 返回类型
<a name="array_except-return-type"></a>

ARRAY\$1EXCEPT 函数返回 SUPER 类型。

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

以下示例显示 ARRAY\$1EXCEPT 函数。

```
SELECT ARRAY_EXCEPT(ARRAY('a','b','c'), ARRAY('b','c','d'));
 array_except
--------------
 ["a"]
(1 row)
```

多集语义：

```
SELECT ARRAY_EXCEPT(ARRAY('b','b','b','b'), ARRAY('b','b'));
 array_except
--------------
 ["b","b"]
(1 row)
```

集语义：

```
SELECT ARRAY_EXCEPT(ARRAY('a','b','b'), ARRAY('b'), TRUE);
 array_except
--------------
 ["a"]
(1 row)
```

NULL 被视为已知对象。

```
SELECT ARRAY_EXCEPT(ARRAY('a',NULL), ARRAY(NULL));
 array_except
--------------
 ["a"]
(1 row)
```

## 另请参阅
<a name="array_except-see-also"></a>
+ [ARRAY\$1INTERSECTION 函数](array_intersection.md)
+ [ARRAY\$1UNION 函数](array_union.md)
+ [ARRAY\$1DISTINCT 函数](array_distinct.md)
+ [ARRAYS\$1OVERLAP 函数](arrays_overlap.md)

# ARRAY\$1FLATTEN 函数
<a name="array_flatten"></a>

将多个数组合并为 SUPER 类型的单个数组。第一个内部数组中的元素首先出现，然后是后续内部数组中的元素。NULL 被视为已知对象。

## 语法
<a name="array_flatten-syntax"></a>

```
ARRAY_FLATTEN( array )
```

## 参数
<a name="array_flatten-arguments"></a>

 *array*   
数组形式的 SUPER 表达式。

## 返回类型
<a name="array_flatten-returm-type"></a>

ARRAY\$1FLATTEN 函数返回 SUPER 类型。

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

以下示例显示 ARRAY\$1FLATTEN 函数。

```
SELECT ARRAY_FLATTEN(ARRAY(ARRAY(1,2,3,4),ARRAY(5,6,7,8),ARRAY(9,10)));
     array_flatten
------------------------
 [1,2,3,4,5,6,7,8,9,10]
(1 row)
```

## 另请参阅
<a name="array_flatten-see-also"></a>
+ [ARRAY\$1CONCAT 函数](r_array_concat.md)
+ [SUBARRAY 函数](r_subarray.md)
+ [ARRAY\$1DISTINCT 函数](array_distinct.md)

# ARRAY\$1INTERSECTION 函数
<a name="array_intersection"></a>

返回一个新数组，其中仅包含两个输入数组中都存在的元素。该函数是 NULL 安全的，这意味着它将 NULL 视为已知对象。无法保证结果中元素的顺序。

## 语法
<a name="array_intersection-syntax"></a>

```
ARRAY_INTERSECTION( array1, array2 [, distinct] )
```

## 参数
<a name="array_intersection-arguments"></a>

 *array1*   
一个用于指定数组的 SUPER 表达式。

 *array2*   
一个用于指定数组的 SUPER 表达式。

 *区分*   
一个布尔值，用于指定是否只返回不同的元素：  
+ *distinct* = FALSE：多集语义适用。重复的元素会被保留，结果中每个元素的频率等于其在两个输入数组中的频率最小值。
+ *distinct* = TRUE：集合语义适用。只返回两个数组共有的唯一元素，没有重复元素。
默认值为 FALSE。

## 返回类型
<a name="array_intersection-return-type"></a>

ARRAY\$1INTERSECTION 函数返回 SUPER 类型。

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

以下示例显示 ARRAY\$1INTERSECTION 函数。

```
SELECT ARRAY_INTERSECTION(ARRAY('a','b','c'), ARRAY('b','c','d'));
 array_intersection 
--------------------
 ["b","c"]
(1 row)
```

多集语义：

```
SELECT ARRAY_INTERSECTION(ARRAY('a','b','b'), ARRAY('b','b','b'));
 array_intersection 
--------------------
 ["b","b"]
(1 row)
```

集语义：

```
SELECT ARRAY_INTERSECTION(ARRAY('a','b','b'), ARRAY('b','b','b'), TRUE);
 array_intersection 
--------------------
 ["b"]
(1 row)
```

NULL 被视为已知对象。

```
SELECT ARRAY_INTERSECTION(ARRAY('a',NULL), ARRAY('b',NULL));
 array_intersection 
--------------------
 [null]
(1 row)
```

## 另请参阅
<a name="array_intersection-see-also"></a>
+ [ARRAY\$1EXCEPT 函数](array_except.md)
+ [ARRAYS\$1OVERLAP 函数](arrays_overlap.md)
+ [ARRAY\$1UNION 函数](array_union.md)
+ [ARRAY\$1DISTINCT 函数](array_distinct.md)

# ARRAY\$1POSITION 函数
<a name="array_position"></a>

返回数组中指定的元素首次出现的位置（索引）。索引从 0 开始，其中 0 表示第一个元素，1 表示第二个元素，以此类推。如果在数组中找不到该元素，则返回 -1。

该函数仅返回第一次出现的位置。要查找所有出现位置，请考虑使用 [ARRAY\$1POSITIONS 函数](array_positions.md) 函数。

## 语法
<a name="array_position-syntax"></a>

```
ARRAY_POSITION( array, value [, null_match] )
```

## 参数
<a name="array_position-arguments"></a>

 *array*   
一个 SUPER 表达式，用于指定要在其中进行搜索的数组。

 *值*   
一个值，用于指定要搜索的元素。

 *null\$1match*   
一个布尔值，用于指定如何处理 NULL 值：  
+ *null\$1match* = FALSE：搜索 NULL 将返回 NULL。如果数组包含 NULL 值，但找不到与非 NULL 搜索值匹配的值，则返回 NULL。
+ *null\$1match* = TRUE：NULL 被视为有效、可搜索的元素。如果数组包含 NULL 值，但找不到与非 NULL 搜索值匹配的值，则返回 -1。
默认值为 TRUE。  
也可以通过配置选项指定默认的 NULL 处理：  

```
-- same as null_match = TRUE
SET default_array_search_null_handling to TRUE;
```

## 返回类型
<a name="array_position-return-type"></a>

ARRAY\$1POSITION 函数返回 INT 类型。

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

以下示例显示 ARRAY\$1POSITION 函数。

```
SELECT ARRAY_POSITION(ARRAY('red', 'green'), 'red');
 array_position 
----------------
              0
(1 row)

SELECT ARRAY_POSITION(ARRAY(1, 2, 3), 4);
 array_position 
----------------
             -1
(1 row)

-- only the position of the first occurrence is returned
SELECT ARRAY_POSITION(ARRAY('red', 'green', 'red'), 'red');
 array_position 
----------------
              0
(1 row)
```

以下示例显示 *null\$1match* 设置为 TRUE 时的函数行为。

```
SET default_array_search_null_handling to TRUE;

-- NULL search is enabled
SELECT ARRAY_POSITION(ARRAY('red', NULL, 'green'), NULL);
 array_position 
----------------
              1
(1 row)

-- The array can contain NULLs
SELECT ARRAY_POSITION(ARRAY('red', NULL, 'green'), 'blue', TRUE);
 array_position 
----------------
             -1
(1 row)
```

以下示例显示 *null\$1match* 设置为 FALSE 时的函数行为。请注意，在函数中指定 *null\$1match* 行为将覆盖默认配置设置。

```
-- same as null_match = TRUE
SET default_array_search_null_handling to TRUE;

-- NULL search is disabled. The default behavior is overridden
SELECT ARRAY_POSITION(ARRAY('red', 'green'), NULL, FALSE);
 array_position 
----------------
               
(1 row)

-- same as null_match = FALSE
SET default_array_search_null_handling to FALSE;

-- The array contains NULL and a match is found
SELECT ARRAY_POSITION(ARRAY('red', NULL, 'green'), 'green');
 array_position 
----------------
              2
(1 row)

-- The array contains NULL but no match is found
SELECT ARRAY_POSITION(ARRAY('red', NULL, 'green'), 'blue');
 array_position 
----------------
               
(1 row)
```

## 另请参阅
<a name="array_position-see-also"></a>
+ [ARRAY\$1POSITIONS 函数](array_positions.md)
+ [ARRAY\$1CONTAINS 函数](array_contains.md)
+ [SUBARRAY 函数](r_subarray.md)

# ARRAY\$1POSITIONS 函数
<a name="array_positions"></a>

返回指定的元素出现在输入数组中的位置（索引）的数组。索引从 0 开始，其中 0 表示第一个元素，1 表示第二个元素，以此类推。如果找不到元素，则返回空数组。

## 语法
<a name="array_positions-syntax"></a>

```
ARRAY_POSITIONS( array, value [, null_match] )
```

## 参数
<a name="array_positions-arguments"></a>

 *array*   
一个 SUPER 表达式，用于指定要在其中进行搜索的数组。

 *值*   
一个值，用于指定要搜索的元素。

 *null\$1match*   
一个布尔值，用于指定如何处理 NULL 值：  
+ *null\$1match* = FALSE：搜索 NULL 将返回 NULL。如果数组包含 NULL 值，但找不到与非 NULL 搜索值匹配的值，则返回 NULL。
+ *null\$1match* = TRUE：NULL 被视为有效、可搜索的元素。如果数组包含 NULL 值，但找不到与非 NULL 搜索值匹配的值，则它将返回一个空数组。
默认值为 TRUE。  
也可以通过配置选项指定默认的 NULL 处理：  

```
-- same as null_match = TRUE
SET default_array_search_null_handling to TRUE;
```

## 返回类型
<a name="array_positions-return-type"></a>

ARRAY\$1POSITIONS 函数返回 SUPER 类型。

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

以下示例显示 ARRAY\$1POSITIONS 函数。

```
SELECT ARRAY_POSITIONS(ARRAY('red', 'green', 'red'), 'red');
 array_positions 
-----------------
 [0,2]
(1 row)

SELECT ARRAY_POSITIONS(ARRAY(1, 2, 3), 4);
 array_positions 
-----------------
 []
(1 row)
```

以下示例显示 *null\$1match* 设置为 TRUE 时的函数行为。

```
SET default_array_search_null_handling to TRUE;

-- NULL search is enabled
SELECT ARRAY_POSITIONS(ARRAY('red', NULL, 'green', NULL), NULL);
 array_positions 
-----------------
 [1,3]
(1 row)

-- The array can contain NULLs
SELECT ARRAY_POSITIONS(ARRAY('red', NULL, 'green'), 'blue', TRUE);
 array_positions 
-----------------
 []
(1 row)
```

以下示例显示 *null\$1match* 设置为 FALSE 时的函数行为。请注意，在函数中指定 *null\$1match* 行为将覆盖默认配置设置。

```
-- same as null_match = TRUE
SET default_array_search_null_handling to TRUE;

-- NULL search is disabled. The default behavior is overridden
SELECT ARRAY_POSITIONS(ARRAY('red', 'green'), NULL, FALSE);
 array_positions 
-----------------
 
(1 row)

-- same as null_match = FALSE
SET default_array_search_null_handling to FALSE;

-- The array contains NULL and a match is found
SELECT ARRAY_POSITIONS(ARRAY('red', NULL, 'green'), 'green');
 array_positions 
-----------------
 [2]
(1 row)

-- The array contains NULL but no match is found
SELECT ARRAY_POSITIONS(ARRAY('red', NULL, 'green'), 'blue');
 array_positions 
-----------------
 
(1 row)
```

## 另请参阅
<a name="array_positions-see-also"></a>
+ [ARRAY\$1POSITION 函数](array_position.md)
+ [ARRAY\$1CONTAINS 函数](array_contains.md)
+ [SUBARRAY 函数](r_subarray.md)

# ARRAY\$1SORT 函数
<a name="array_sort"></a>

按升序或降序创建输入数组的排序版本。您可以指定 NULL 值应在结果中出现的位置。该函数是 NULL 安全的，这意味着它将 NULL 视为已知对象。

## 语法
<a name="array_sort-syntax"></a>

```
ARRAY_SORT( array [, sort_ascending [, nulls_first]] )
```

## 参数
<a name="array_sort-arguments"></a>

 *array*   
一个 SUPER 表达式，用于指定要排序的数组。

 *sort\$1ascending*   
一个布尔值，用于指定是按升序还是降序对数组进行排序：  
+ 指定 TRUE 可按升序对元素进行排序。
+ 指定 FALSE 可按降序对元素进行排序。
默认值为 TRUE。

 *nulls\$1first*   
一个用于指定 NULL 定位的布尔值：  
+ 指定 TRUE 可将 NULL 放在已排序数组的开头。
+ 指定 FALSE 可将 NULL 放在已排序数组的末尾。

## 返回类型
<a name="array_sort-return-type"></a>

ARRAY\$1SORT 函数返回 SUPER 类型。

## 注意
<a name="array_sort-note"></a>

当对包含混合数据类型的数组进行排序时，将根据以下类型优先顺序对元素进行排序：
+ 布尔值
+ 数字值
+ 字符串值
+ 数组
+ 对象/词典

在每个类型类别中，元素根据其自然顺序进行排序（例如，数字按数值大小排序，字符串按字母顺序排序）。

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

以下示例显示 ARRAY\$1SORT 函数。

```
-- Ascending order (default)
SELECT ARRAY_SORT(ARRAY('b', 'a', 0, NULL, 1, false));
        array_sort        
--------------------------
 [false,0,1,"a","b",null]
(1 row)

-- Descending order
SELECT ARRAY_SORT(ARRAY('b', 'a', 0, NULL, 1, false), False);
        array_sort        
--------------------------
 [null,"b","a",1,0,false]
(1 row)

-- Descending order with NULLs at the end of the sorted array
SELECT ARRAY_SORT(ARRAY('b', 'a', 0, NULL, 1, false), False, False);
        array_sort        
--------------------------
 ["b","a",1,0,false,null]
(1 row)
```

## 另请参阅
<a name="array_sort-see-also"></a>
+ [ARRAY\$1DISTINCT 函数](array_distinct.md)
+ [ARRAY\$1FLATTEN 函数](array_flatten.md)
+ [SUBARRAY 函数](r_subarray.md)

# ARRAY\$1UNION 函数
<a name="array_union"></a>

合并两个数组并返回一个包含所有唯一值的数组，同时移除所有重复的值。该函数是 NULL 安全的，这意味着它将 NULL 视为已知对象。无法保证结果中元素的顺序。

## 语法
<a name="array_union-syntax"></a>

```
ARRAY_UNION( array1, array2 )
```

## 参数
<a name="array_union-arguments"></a>

 *array1*   
一个用于指定第一个数组的 SUPER 表达式。

 *array2*   
一个用于指定第二个数组的 SUPER 表达式。

## 返回类型
<a name="array_union-return-type"></a>

ARRAY\$1UNION 函数返回 SUPER 类型。

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

以下示例显示 ARRAY\$1UNION 函数。

```
SELECT ARRAY_UNION(ARRAY('a','b','b'), ARRAY('b','c','c'));
  array_union  
---------------
 ["a","b","c"]
(1 row)
```

无法保证元素的顺序：

```
SELECT ARRAY_UNION(ARRAY('b','a','b'), ARRAY(NULL,'b',NULL));
  array_union   
----------------
 ["b","a",null]
(1 row)
```

## 另请参阅
<a name="array_union-see-also"></a>
+ [ARRAY\$1CONCAT 函数](r_array_concat.md)
+ [ARRAY\$1DISTINCT 函数](array_distinct.md)
+ [ARRAY\$1INTERSECTION 函数](array_intersection.md)
+ [ARRAY\$1EXCEPT 函数](array_except.md)

# ARRAYS\$1OVERLAP 函数
<a name="arrays_overlap"></a>

检查两个数组是否有任何公共元素。如果数组共享至少一个元素，则返回 TRUE；如果不存在公共元素，则返回 FALSE。该函数是 NULL 安全的，这意味着它将 NULL 视为已知对象。

## 语法
<a name="arrays_overlap-syntax"></a>

```
ARRAYS_OVERLAP( array1, array2 )
```

## 参数
<a name="arrays_overlap-arguments"></a>

 *array1*   
一个用于指定数组的 SUPER 表达式。

 *array2*   
一个用于指定数组的 SUPER 表达式。

## 返回类型
<a name="arrays_overlap-return-type"></a>

ARRAYS\$1OVERLAP 函数返回 Boolean 类型。

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

以下示例显示 ARRAYS\$1OVERLAP 函数。

```
SELECT ARRAYS_OVERLAP(ARRAY('blue', 'green'), ARRAY('red', 'green'));
 arrays_overlap 
----------------
 t
(1 row)
```

以下示例显示 NULL 被视为有效元素。

```
SELECT ARRAYS_OVERLAP(ARRAY('red', NULL, 'blue'), ARRAY('green', NULL));
 arrays_overlap 
----------------
 t
(1 row)

SELECT ARRAYS_OVERLAP(ARRAY('red', NULL, 'blue'), ARRAY('green'));
 arrays_overlap 
----------------
 f
(1 row)

SELECT ARRAYS_OVERLAP(JSON_PARSE('[null]'), ARRAY(NULL));
 arrays_overlap 
----------------
 t
(1 row)
```

## 另请参阅
<a name="arrays_overlap-see-also"></a>
+ [ARRAY\$1INTERSECTION 函数](array_intersection.md)
+ [ARRAY\$1CONTAINS 函数](array_contains.md)
+ [ARRAY\$1EXCEPT 函数](array_except.md)

# GET\$1ARRAY\$1LENGTH 函数
<a name="get_array_length"></a>

在给定对象或数组路径的情况下返回 SUPER 数组的长度。

## 语法
<a name="get_array_length-syntax"></a>

```
GET_ARRAY_LENGTH( super_expr )
```

## 参数
<a name="get_array_length-arguments"></a>

 *super\$1expr*   
数组形式的有效 SUPER 表达式。

## 返回类型
<a name="get_array_length-returm-type"></a>

GET\$1ARRAY\$1LENGTH 函数返回 INT。

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

以下示例显示 GET\$1ARRAY\$1LENGTH 函数。

```
SELECT GET_ARRAY_LENGTH(ARRAY(1,2,3,4,5,6,7,8,9,10));
 get_array_length
----------------------
            10
(1 row)
```

# SPLIT\$1TO\$1ARRAY 函数
<a name="split_to_array"></a>

将分隔符用作可选参数。如果不存在分隔符，则默认值为逗号。

## 语法
<a name="split_to_array-syntax"></a>

```
SPLIT_TO_ARRAY( string, delimiter )
```

## 参数
<a name="split_to_array-arguments"></a>

 **string**   
要拆分的输入字符串。

 **分隔符**   
输入字符串将在其上拆分的可选值。默认值为逗号。

## 返回类型
<a name="split_to_array-return-type"></a>

SPLIT\$1TO\$1ARRAY 函数返回一个 SUPER 数据值。

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

以下示例显示 SPLIT\$1TO\$1ARRAY 函数。

```
SELECT SPLIT_TO_ARRAY('12|345|6789', '|');
     split_to_array
-------------------------
 ["12","345","6789"]
(1 row)
```

## 另请参阅
<a name="split_to_array-see-also"></a>
+ [ARRAY 函数](r_array.md)
+ [ARRAY\$1CONCAT 函数](r_array_concat.md)
+ [SUBARRAY 函数](r_subarray.md)
+ [ARRAY\$1FLATTEN 函数](array_flatten.md)

# SUBARRAY 函数
<a name="r_subarray"></a>

从指定的位置开始提取数组的一部分。返回一个新数组，其中包含输入数组中指定数量的元素。

## 语法
<a name="r_subarray-syntax"></a>

```
SUBARRAY( super_expr, start_position, length )
```

## 参数
<a name="r_subarray-arguments"></a>

*super\$1expr*  
数组形式的有效 SUPER 表达式。

*start\$1position*  
一个整数，用于指定提取的起始位置。索引从 0 开始，其中 0 表示第一个元素。如果 start\$1position 超过数组长度，则返回一个空数组。

*length*  
一个可选的整数，用于指定要提取的元素数。如果忽略，则返回数组从起始位置到末尾的所有元素。

## 返回类型
<a name="r_subarray-return-type"></a>

SUBARRAY 函数返回一个 SUPER 数据值。

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

以下是 SUBARRAY 函数的示例。

```
 SELECT SUBARRAY(ARRAY('a', 'b', 'c', 'd', 'e', 'f'), 2, 3);
   subarray
---------------
 ["c","d","e"]
(1 row)
```

## 另请参阅
<a name="r_subarray-see-also"></a>
+ [ARRAY\$1POSITION 函数](array_position.md)
+ [ARRAY\$1POSITIONS 函数](array_positions.md)
+ [ARRAY\$1FLATTEN 函数](array_flatten.md)
+ [ARRAY\$1CONCAT 函数](r_array_concat.md)

# 按位聚合函数
<a name="c_bitwise_aggregate_functions"></a>

按位聚合函数会进行位运算，以聚合整数列和可转换或舍入为整数值的列。

**Topics**
+ [在按位聚合中使用 NULL](#c_bitwise_aggregate_functions-nulls-in-bit-wise-aggregations)
+ [按位聚合的 DISTINCT 支持](#distinct-support-for-bit-wise-aggregations)
+ [按位函数的概述示例](#r_bitwise_example)
+ [BIT\$1AND 函数](r_BIT_AND.md)
+ [BIT\$1OR 函数](r_BIT_OR.md)
+ [BOOL\$1AND 函数](r_BOOL_AND.md)
+ [BOOL\$1OR 函数](r_BOOL_OR.md)

## 在按位聚合中使用 NULL
<a name="c_bitwise_aggregate_functions-nulls-in-bit-wise-aggregations"></a>

在将按位函数应用于可为 null 的列时，在计算函数结果之前将消除任何 NULL 值。如果没有行符合聚合资格，则按位函数将返回 NULL。相同的行为适用于常规的聚合函数。以下为示例。

```
select sum(venueseats), bit_and(venueseats) from venue
where venueseats is null;

sum  | bit_and
------+---------
null |    null
(1 row)
```

## 按位聚合的 DISTINCT 支持
<a name="distinct-support-for-bit-wise-aggregations"></a>

与其他聚合函数相同的是，按位函数也支持 DISTINCT 关键字。

但是，将 DISTINCT 用于这些函数不会影响结果。值的第一个实例足以满足按位 AND 或 OR 操作。如果重复值出现在正在计算的表达式中，不会造成任何差异。

由于 DISTINCT 处理可能会产生一些查询执行开销，我们建议不要将 DISTINCT 用于按位函数。

## 按位函数的概述示例
<a name="r_bitwise_example"></a>

下面，您可以找到一些概述示例，说明如何使用按位函数。您还可以通过每个函数描述找到具体的代码示例。

按位函数的示例以 TICKIT 示例数据库为基础。TICKIT 示例数据库中的 USERS 表包含多个布尔列，该类列指示每个用户是否喜欢各种类型的活动，如运动、戏剧、歌剧等。下面是一个示例。

```
select userid, username, lastname, city, state, 
likesports, liketheatre
from users limit 10;

userid | username | lastname  |     city     | state | likesports | liketheatre
-------+----------+-----------+--------------+-------+------------+-------------
1 | JSG99FHE | Taylor    | Kent         | WA    | t          | t
9 | MSD36KVR | Watkins   | Port Orford  | MD    | t          | f
```

假定新版本的 USERS 表是以不同的方式构建的。在此新版本中，包含一个整数列，该列定义（以二进制格式）每个用户喜欢或不喜欢的 8 种类型的事件。在此设计中，每个位位置均代表一类活动。某个喜欢全部 8 种类型的用户已将全部 8 个位设置为 1（如下表的第一行中所示）。不喜欢任何这些活动的用户已将全部 8 个位设置为 0（请见第二行）。仅喜欢运动和爵士乐的用户显示在以下第三行中：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/c_bitwise_aggregate_functions.html)

在数据库表中，这些二进制值可作为整数存储在一个 LIKES 列中，如下所示。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/c_bitwise_aggregate_functions.html)

# BIT\$1AND 函数
<a name="r_BIT_AND"></a>

BIT\$1AND 函数会对单个整数列或表达式中的所有值运行按位 AND 运算。此函数会聚合与表达式中的每个整数值对应的每个二进制值的每个位。

如果所有值中没有设置为 1 的位，则 BIT\$1AND 函数将返回结果 `0`。如果所有值中的一个或多个位设置为 1，该函数返回一个整数值。此整数是对应于这些位的二进制值的数字。

例如，表中的一个列包含 4 个整数值：3、7、10 和 22。这些整数用二进制格式表示，如下所示：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_BIT_AND.html)

针对此数据集的 BIT\$1AND 操作发现所有位仅在倒数第二的位置设置为 `1`。结果是一个二进制值 `00000010`，它表示整数值 `2`。因此，BIT\$1AND 函数返回 `2`。

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

```
BIT_AND ( [DISTINCT | ALL] expression )
```

## 参数
<a name="r_BIT_AND-arguments"></a>

 *expression*   
对其执行函数的目标列或表达式。此表达式必须具有 INT、INT2 或 INT8 数据类型。该函数返回等同的 INT、INT2 或 INT8 数据类型。

DISTINCT \$1 ALL  
利用参数 DISTINCT，该函数可在计算结果之前消除指定表达式的所有重复值。利用参数 ALL，该函数可保留所有重复值。ALL 是默认值。有关更多信息，请参阅 [按位聚合的 DISTINCT 支持](c_bitwise_aggregate_functions.md#distinct-support-for-bit-wise-aggregations)。

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

假定有意义的商业信息存储在整数列中，您可使用按位函数提取和聚合该信息。以下查询将 BIT\$1AND 函数应用于名为“USERLIKES”的表的 LIKES 列中并按 CITY 列对结果进行分组。

```
select city, bit_and(likes) from userlikes group by city 
order by city;
city          | bit_and
--------------+---------
Los Angeles   |       0
Sacramento    |       0
San Francisco |       0
San Jose      |      64
Santa Barbara |     192
(5 rows)
```

您可以将这些结果解释如下：
+ Santa Barbara 的整数值 `192` 转换为二进制值 `11000000`。换句话说，此城市中的所有用户都喜欢运动和戏剧，但并非所有用户都喜欢任何其他类型的活动。
+ 整数 `64` 转换为 `01000000`。因此，对于圣荷西的所有用户来说，他们喜欢的唯一活动类型是戏剧。
+ 其他三个城市的值 `0` 表示这些城市中的所有用户没有共同的“喜好”。

# BIT\$1OR 函数
<a name="r_BIT_OR"></a>

BIT\$1OR 函数会对单个整数列或表达式中的所有值运行按位 OR 运算。此函数会聚合与表达式中的每个整数值对应的每个二进制值的每个位。

例如，假设您的表中的一个列包含 4 个整数值：3、7、10 和 22。这些整数用二进制格式表示，如下所示。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_BIT_OR.html)

如果将 BIT\$1OR 函数应用于整数值集合，则该操作将查找 `1` 在每个位置找到的任何值。在这种情况下，`1` 存在于至少一个值的后 5 个位置，从而生成二进制结果 `00011111`；因此，该函数将返回 `31`（或 `16 + 8 + 4 + 2 + 1`）。

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

```
BIT_OR ( [DISTINCT | ALL] expression )
```

## 参数
<a name="r_BIT_OR-arguments"></a>

 *expression*   
对其执行函数的目标列或表达式。此表达式必须具有 INT、INT2 或 INT8 数据类型。该函数返回等同的 INT、INT2 或 INT8 数据类型。

DISTINCT \$1 ALL  
利用参数 DISTINCT，该函数可在计算结果之前消除指定表达式的所有重复值。利用参数 ALL，该函数可保留所有重复值。ALL 是默认值。有关更多信息，请参阅 [按位聚合的 DISTINCT 支持](c_bitwise_aggregate_functions.md#distinct-support-for-bit-wise-aggregations)。

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

以下查询会将 BIT\$1OR 函数应用于名为“USERLIKES”的表的 LIKES 列并按 CITY 列对结果进行分组。

```
select city, bit_or(likes) from userlikes group by city
order by city;
city          | bit_or
--------------+--------
Los Angeles   |    127
Sacramento    |    255
San Francisco |    255
San Jose      |    255
Santa Barbara |    255
(5 rows)
```

对于所列的四个城市，至少有一个用户喜欢全部活动类型 (`255=11111111`)。对于洛杉矶，至少有一个用户喜欢除运动之外的所有活动类型 (`127=01111111`)。

# BOOL\$1AND 函数
<a name="r_BOOL_AND"></a>

BOOL\$1AND 函数在单个布尔/整数列或表达式上运行。此函数将类似的逻辑应用于 BIT\$1AND 和 BIT\$1OR 函数。对于此函数，返回类型为布尔值（`true` 或 `false`）。

如果集合中的所有值为 true，则 BOOL\$1AND 函数返回 `true` (`t`)。如果任何值为 false，该函数返回 `false` (`f`)。

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

```
BOOL_AND ( [DISTINCT | ALL] expression )
```

## 参数
<a name="r_BOOL_AND-arguments"></a>

 *expression*   
对其执行函数的目标列或表达式。此表达式必须具有 BOOLEAN 或整数数据类型。该函数的返回类型为 BOOLEAN。

DISTINCT \$1 ALL  
利用参数 DISTINCT，该函数可在计算结果之前消除指定表达式的所有重复值。利用参数 ALL，该函数可保留所有重复值。ALL 是默认值。有关更多信息，请参阅 [按位聚合的 DISTINCT 支持](c_bitwise_aggregate_functions.md#distinct-support-for-bit-wise-aggregations)。

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

您可以对布尔表达式或整数表达式使用布尔函数。例如，以下查询从 TICKIT 数据库中的标准 USERS 表返回结果，该表包含多个布尔列。

BOOL\$1AND 函数对所有 5 个行返回 `false`。并非每个州的所有用户都喜欢运动。

```
select state, bool_and(likesports) from users 
group by state order by state limit 5;

state | bool_and
------+---------
AB    | f
AK    | f
AL    | f
AZ    | f
BC    | f
(5 rows)
```

# BOOL\$1OR 函数
<a name="r_BOOL_OR"></a>

BOOL\$1OR 函数在单个布尔/整数列或表达式上运行。此函数将类似的逻辑应用于 BIT\$1AND 和 BIT\$1OR 函数。对于此函数，返回类型为布尔值（`true`、`false` 或 `NULL`）。

如果集合中的一个或多个值为 `true`，则 BOOL\$1OR 函数返回 `true`（`t`）。如果集合中的所有值为 `false`，则函数返回 `false`（`f`）。如果值未知，则可以返回 NULL。

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

```
BOOL_OR ( [DISTINCT | ALL] expression )
```

## 参数
<a name="r_BOOL_OR-arguments"></a>

 *expression*   
对其执行函数的目标列或表达式。此表达式必须具有 BOOLEAN 或整数数据类型。该函数的返回类型为 BOOLEAN。

DISTINCT \$1 ALL  
利用参数 DISTINCT，该函数可在计算结果之前消除指定表达式的所有重复值。利用参数 ALL，该函数可保留所有重复值。ALL 是默认值。请参阅 [按位聚合的 DISTINCT 支持](c_bitwise_aggregate_functions.md#distinct-support-for-bit-wise-aggregations)。

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

您可以将布尔函数与布尔表达式或整数表达式结合使用。例如，以下查询从 TICKIT 数据库中的标准 USERS 表返回结果，该表包含多个布尔列。

BOOL\$1OR 函数对所有 5 个行返回 `true`。每个州中至少有一个用户喜欢运动。

```
select state, bool_or(likesports) from users 
group by state order by state limit 5;

state | bool_or 
------+--------
AB    | t      
AK    | t      
AL    | t       
AZ    | t       
BC    | t       
(5 rows)
```

以下示例返回 NULL。

```
SELECT BOOL_OR(NULL = '123')
               bool_or
------                  
NULL
```

# 条件表达式
<a name="c_conditional_expressions"></a>

**Topics**
+ [CASE 条件表达式](r_CASE_function.md)
+ [DECODE 函数](r_DECODE_expression.md)
+ [GREATEST 和 LEAST 函数](r_GREATEST_LEAST.md)
+ [NVL 和 COALESCE 函数](r_NVL_function.md)
+ [NVL2 函数](r_NVL2.md)
+ [NULLIF 函数](r_NULLIF_function.md)

Amazon Redshift 支持 SQL 标准的扩展的一些条件表达式。

# CASE 条件表达式
<a name="r_CASE_function"></a>

CASE 表达式是一种条件表达式，类似于其他语言中发现的 if/then/else 语句。CASE 用于指定存在多个条件时的结果。在 SQL 表达式有效的情况下使用 CASE，例如在 SELECT 命令中。

有两种类型的 CASE 表达式：简单和搜索。
+ 在简单 CASE 表达式中，将一个表达式与一个值比较。在找到匹配项时，将应用 THEN 子句中的指定操作。如果未找到匹配项，则应用 ELSE 子句中的操作。
+ 在搜索 CASE 表达式中，基于布尔表达式计算每个 CASE，而且 CASE 语句会返回第一个匹配的 CASE。如果在 WHEN 子句中未找到匹配，则返回 ELSE 子句中的操作。

## 语法
<a name="r_CASE_function-syntax"></a>

用于匹配条件的简单 CASE 语句：

```
CASE expression
  WHEN value THEN result
  [WHEN...]
  [ELSE result]
END
```

用于计算每个条件的搜索 CASE 语句：

```
CASE
  WHEN condition THEN result
  [WHEN ...]
  [ELSE result]
END
```

## 参数
<a name="r_CASE_function-arguments"></a>

 *expression*   
一个列名称或任何有效的表达式。

 *值*   
与该表达式比较的值，如数字常数或字符串。

 *result*   
计算表达式或布尔条件时返回的目标值或表达式。所有结果表达式的数据类型必须可转换为单一输出类型。

 *条件*   
计算结果为 true 或 false 的 Boolean 表达式。如果 *condition* 为 true，则 CASE 表达式的值是符合条件的结果，不处理 CASE 表达式的其余部分。如果 *condition* 为 false，则计算任何后续的 WHEN 子句。如果没有 WHEN 条件结果为 true，则 CASE 表达式的值是 ELSE 子句的结果。如果没有 ELSE 子句且没有条件为 true，则结果为 null。

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

以下示例使用 TICKIT 样本数据中的 VENUE 表和 SALES 表。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

使用简单 CASE 表达式在针对 VENUE 表的查询中将 `New York City` 替换为 `Big Apple`。将所有其他城市名称替换为 `other`。

```
select venuecity,
  case venuecity
    when 'New York City'
    then 'Big Apple' else 'other'
  end 
from venue
order by venueid desc;

venuecity        |   case
-----------------+-----------
Los Angeles      | other
New York City    | Big Apple
San Francisco    | other
Baltimore        | other
...
```

使用搜索 CASE 表达式来基于单个门票销售的 PRICEPAID 值分配组编号：

```
select pricepaid,
  case when pricepaid <10000 then 'group 1'
    when pricepaid >10000 then 'group 2'
    else 'group 3'
  end 
from sales
order by 1 desc;

pricepaid |  case
----------+---------
12624     | group 2
10000     | group 3
10000     | group 3
9996      | group 1
9988      | group 1
...
```

# DECODE 函数
<a name="r_DECODE_expression"></a>

DECODE 表达式将一个特定值替换为另一个特定值或默认值，具体取决于等式条件的结果。此操作等同于简单 CASE 表达式或 IF-THEN-ELSE 语句的操作。

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

```
DECODE ( expression, search, result [, search, result ]... [ ,default ] )
```

此类表达式对于将存储在表中的缩写或代码替换为报表所需的有意义的业务值非常有用。

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

 *expression*   
要比较的值的源，如表中的列。

 *搜索*   
与源表达式比较的目标值，如数字值或字符串。搜索表达式的计算结果必须为一个固定值。您无法指定计算结果为值范围（如 `age between 20 and 29`）的表达式；您需要为要替换的每个值指定单独的搜索/结果对。  
搜索表达式的所有实例的数据类型必须相同或兼容。*expression* 和 *search* 参数也必须兼容。

 *result*   
查询在表达式匹配搜索值时返回的替换值。您必须在 DECODE 表达式中包含至少一个搜索/结果对。  
结果表达式的所有实例的数据类型必须相同或兼容。*result* 和 *default* 参数也必须兼容。

 *默认值*   
搜索条件失败时用于案例的可选默认值。如果您未指定默认值，则 DECODE 表达式返回 NULL。

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

如果 *expression* 值和 *search* 值都为 NULL，则 DECODE 结果为对应的 *result* 值。有关此函数的使用的说明，请参阅“示例”部分。

以此方式使用时，DECODE 类似于 [NVL2 函数](r_NVL2.md)，但存在一些区别。有关这些区别的说明，请参阅 NVL2 使用说明。

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

当值 `2008-06-01` 存在于 datetable 的 caldate 列中时，以下示例会将该值替换为 `June 1st, 2008`。此示例将所有其他 caldate 值替换为 NULL。

```
select decode(caldate, '2008-06-01', 'June 1st, 2008')
from datetable where month='JUN' order by caldate;

case
----------------
June 1st, 2008

...
(30 rows)
```

以下示例使用 DECODE 表达式将 CATEGORY 表中的 5 个缩写的 CATNAME 列转换为全名并将该列中的其他值转换为 `Unknown`。

```
select catid, decode(catname,
'NHL', 'National Hockey League',
'MLB', 'Major League Baseball',
'MLS', 'Major League Soccer',
'NFL', 'National Football League',
'NBA', 'National Basketball Association',
'Unknown')
from category
order by catid;

catid  |	case
-------+---------------------------------
1      | Major League Baseball
2      | National Hockey League
3      | National Football League
4      | National Basketball Association
5      | Major League Soccer
6      | Unknown
7      | Unknown
8      | Unknown
9      | Unknown
10     | Unknown
11     | Unknown
(11 rows)
```

使用 DECODE 表达式在 VENUESEATS 列中查找带 NULL 值的科罗拉多州和内华达州的 5 个场地；将这些 NULL 值转换为零。如果 VENUESEATS 列不为 NULL，则返回 1 作为结果。

```
select venuename, venuestate, decode(venueseats,null,0,1)
from venue
where venuestate in('NV','CO')
order by 2,3,1;

venuename	              | venuestate     | case
------------------------------+----------------+-----------
Coors Field                   |	CO	       |   1
Dick's Sporting Goods Park    |	CO	       |   1
Ellie Caulkins Opera House    |	CO	       |   1
INVESCO Field		      |	CO	       |   1
Pepsi Center		      |	CO	       |   1
Ballys Hotel		      |	NV	       |   0
Bellagio Hotel                |	NV	       |   0
Caesars Palace                |	NV	       |   0
Harrahs Hotel                 |	NV	       |   0
Hilton Hotel                  |	NV	       |   0
...						
(20 rows)
```

# GREATEST 和 LEAST 函数
<a name="r_GREATEST_LEAST"></a>

从包含任何数量的表达式的列表中返回最大值或最小值。

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

```
GREATEST (value [, ...])
LEAST (value [, ...])
```

## 参数
<a name="r_GREATEST_LEAST-arguments"></a>

*expression\$1list*  
表达式的逗号分隔的列表，如列名称。这些表达式都必须可转换为常见数据类型。忽略该列表中的 NULL 值。如果所有表达式的计算结果为 NULL，则结果为 NULL。

## 返回值
<a name="r_GREATEST_LEAST-returns"></a>

从所提供的表达式列表中返回最大值（对于 GREATEST）或最小值（对于 LEAST）。

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

以下示例按字母顺序返回 `firstname` 或 `lastname` 的最高值。

```
select firstname, lastname, greatest(firstname,lastname) from users
where userid < 10
order by 3;

 firstname | lastname  | greatest
-----------+-----------+-----------
 Lars      | Ratliff   | Ratliff
 Reagan    | Hodge     | Reagan
 Colton    | Roy       | Roy
 Barry     | Roy       | Roy
 Tamekah   | Juarez    | Tamekah
 Rafael    | Taylor    | Taylor
 Victor    | Hernandez | Victor
 Vladimir  | Humphrey  | Vladimir
 Mufutau   | Watkins   | Watkins
(9 rows)
```

# NVL 和 COALESCE 函数
<a name="r_NVL_function"></a>

返回表达式系列中不为 null 的第一个表达式的值。当找到非 null 值时，将不计算该列表中的剩余表达式。

NVL 与 COALESCE 相同。它们是同义词。本主题说明了其语法，并提供这两者的示例。

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

```
NVL( expression, expression, ... )
```

用于 COALESCE 的语法是相同的：

```
COALESCE( expression, expression, ... )
```

如果所有表达式为 null，则结果为 null。

如果您要在主要值缺失或为 null 时返回次要值，则这些函数非常有用。例如，一个查询可能会返回前三个可用电话号码中的第一个：手机、家庭或工作号码。函数中表达式的顺序决定了计算结果的顺序。

## 参数
<a name="r_NVL_function-arguments"></a>

 *expression*   
一个要针对 null 状态进行计算的表达式，如列名称。

## 返回类型
<a name="r_NVL_function-returntype"></a>

Amazon Redshift 根据输入表达式确定返回值的数据类型。如果输入表达式的数据类型不是通用类型，则会返回错误。

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

如果列表包含整数表达式，则该函数返回一个整数。

```
SELECT COALESCE(NULL, 12, NULL);

coalesce
--------------
12
```

此示例与前面的示例相同（不同之处在于它使用 NVL），返回相同的结果。

```
SELECT NVL(NULL, 12, NULL);

coalesce
--------------
12
```

以下示例返回字符串类型。

```
SELECT COALESCE(NULL, 'Amazon Redshift', NULL);

coalesce
--------------
Amazon Redshift
```

以下示例会导致错误，因为表达式列表中的数据类型有变化。在这种情况下，列表中既有字符串类型，也有数字类型。

```
SELECT COALESCE(NULL, 'Amazon Redshift', 12);
ERROR: invalid input syntax for integer: "Amazon Redshift"
```

对于本例，您创建一个包含 START\$1DATE 和 END\$1DATE 列的表，插入几个包含 null 值的行，然后将 NVL 表达式应用于这两个列。

```
create table datetable (start_date date, end_date date);           
insert into datetable values ('2008-06-01','2008-12-31');
insert into datetable values (null,'2008-12-31');
insert into datetable values ('2008-12-31',null);
```

```
select nvl(start_date, end_date)
from datetable
order by 1;
               
coalesce
------------
2008-06-01
2008-12-31
2008-12-31
```

NVL 表达式的默认列名称为 COALESCE。以下查询将返回相同的结果：

```
select coalesce(start_date, end_date)
from datetable
order by 1;
```

在以下示例查询中，您创建一个包含示例酒店预订信息的表，然后插入几行。一些记录包含 null 值。

```
create table booking_info (booking_id int, booking_code character(8), check_in date, check_out date, funds_collected numeric(12,2));
```

插入以下示例数据。一些记录没有 `check_out` 日期或 `funds_collected` 数量。

```
insert into booking_info values (1, 'OCEAN_WV', '2023-02-01','2023-02-03',100.00);
insert into booking_info values (2, 'OCEAN_WV', '2023-04-22','2023-04-26',120.00);
insert into booking_info values (3, 'DSRT_SUN', '2023-03-13','2023-03-16',125.00);
insert into booking_info values (4, 'DSRT_SUN', '2023-06-01','2023-06-03',140.00);
insert into booking_info values (5, 'DSRT_SUN', '2023-07-10',null,null);
insert into booking_info values (6, 'OCEAN_WV', '2023-08-15',null,null);
```

以下查询返回日期列表。如果 `check_out` 日期不可用，它会列出 `check_in` 日期。

```
select coalesce(check_out, check_in)
from booking_info
order by booking_id;
```

结果如下。请注意，最后两条记录显示了 `check_in` 日期。

```
coalesce
------------
2023-02-03
2023-04-26	
2023-03-16	
2023-06-03	
2023-07-10	
2023-08-15
```

如果您希望查询为特定函数或列返回 null 值，则可使用 NVL 表达式将这些 null 值替换为其他一些值。例如，聚合函数（如 SUM）在没有要计算的行时会返回 null 值而不是零。您可以使用 NVL 表达式将这些 null 值替换为 `700.0`。对 `funds_collected` 求和的结果不是 `485`，而是 `1885`，因为值为 null 的两行被替换为 `700`。

```
select sum(nvl(funds_collected, 700.0)) as sumresult from booking_info;
               
sumresult
------
 1885
```

# NVL2 函数
<a name="r_NVL2"></a>

根据指定表达式的计算结果是 NULL 还是 NOT NULL 返回这两个值之一。

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

```
NVL2 ( expression, not_null_return_value, null_return_value )
```

## 参数
<a name="r_NVL2-arguments"></a>

 *expression*   
一个要针对 null 状态进行计算的表达式，如列名称。

 *not\$1null\$1return\$1value*   
在 *expression* 的计算结果为 NOT NULL 时返回的值。*not\$1null\$1return\$1value* 值必须具有与 *expression* 相同的数据类型或可隐式转换为该数据类型。

 *null\$1return\$1value*   
在 *expression* 的计算结果为 NULL 时返回的值。*null\$1return\$1value* 值必须具有与 *expression* 相同的数据类型或可隐式转换为该数据类型。

## 返回类型
<a name="r_NVL2-return-type"></a>

按以下方式确定 NVL2 返回类型：
+ 如果 *not\$1null\$1return\$1value* 或 *null\$1return\$1value* 为 null，则返回非 null 表达式的数据类型。

如果 *not\$1null\$1return\$1value* 和 *null\$1return\$1value* 都不为 null：
+ 如果 *not\$1null\$1return\$1value* 和 *null\$1return\$1value* 具有相同的数据类型，则返回该数据类型。
+ 如果 *not\$1null\$1return\$1value* 和 *null\$1return\$1value* 具有不同的数字数据类型，则返回最小的可兼容数字数据类型。
+ 如果 *not\$1null\$1return\$1value* 和 *null\$1return\$1value* 具有不同的日期时间数据类型，则返回时间戳数据类型。
+ 如果 *not\$1null\$1return\$1value* 和 *null\$1return\$1value* 具有不同的字符数据类型，则返回 *not\$1null\$1return\$1value* 的数据类型。
+ 如果 *not\$1null\$1return\$1value* 和 *null\$1return\$1value* 具有混合的数字和非数字数据类型，则返回 *not\$1null\$1return\$1value* 的数据类型。

**重要**  
在最后两个示例中（其中返回 *not\$1null\$1return\$1value* 的数据类型），*null\$1return\$1value* 将隐式转换为该数据类型。如果数据类型不兼容，则该函数将失败。

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

当 *expression* 和 *search* 参数均为 null 时，[DECODE 函数](r_DECODE_expression.md) 可以通过与 NVL2 类似的方式使用。区别在于：在 DECODE 中，返回内容将同时具有 *result* 参数的值和数据类型。相反，在 NVL2 中，返回内容将具有 *not\$1null\$1return\$1value* 或 *null\$1return\$1value* 参数的值（不管函数选择哪一个），但将具有 *not\$1null\$1return\$1value* 的数据类型。

例如，假定 column1 为 NULL，则以下查询将返回相同的值。但是，DECODE 返回值数据类型将为 INTEGER，NVL2 返回值数据类型将为 VARCHAR。

```
select decode(column1, null, 1234, '2345');
select nvl2(column1, '2345', 1234);
```

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

以下示例修改一些示例数据，然后计算两个字段以为用户提供相应的联系人信息：

```
update users set email = null where firstname = 'Aphrodite' and lastname = 'Acevedo';

select (firstname + ' ' + lastname) as name, 
nvl2(email, email, phone) AS contact_info
from users 
where state = 'WA'
and lastname  like 'A%'
order by lastname, firstname;

name			     contact_info	
--------------------+-------------------------------------------
Aphrodite Acevedo	(906) 632-4407
Caldwell Acevedo 	Nunc.sollicitudin@Duisac.ca
Quinn Adams		  vel@adipiscingligulaAenean.com
Kamal Aguilar		quis@vulputaterisusa.com
Samson Alexander	 hendrerit.neque@indolorFusce.ca
Hall Alford		  ac.mattis@vitaediamProin.edu
Lane Allen		   et.netus@risusDonec.org
Xander Allison	   ac.facilisis.facilisis@Infaucibus.com
Amaya Alvarado	   dui.nec.tempus@eudui.edu
Vera Alvarez		 at.arcu.Vestibulum@pellentesque.edu
Yetta Anthony		enim.sit@risus.org
Violet Arnold		ad.litora@at.com
August Ashley		consectetuer.euismod@Phasellus.com
Karyn Austin		 ipsum.primis.in@Maurisblanditenim.org
Lucas Ayers		  at@elitpretiumet.com
```

# NULLIF 函数
<a name="r_NULLIF_function"></a>

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

NULLIF 表达式比较两个参数并在两个参数相等时返回 null。如果两个参数不相等，则返回第一个参数。此表达式为 NVL 或 COALESCE 表达式的反向表达式。

```
NULLIF ( expression1, expression2 )
```

## 参数
<a name="r_NULLIF_function-arguments"></a>

 *expression1，expression2*   
所比较的目标列或表达式。返回类型与第一个表达式的类型相同。NULLIF 结果的默认列名称为第一个表达式的列名称。

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

在以下示例中，查询返回字符串 `first`，因为参数不相等。

```
SELECT NULLIF('first', 'second');

case
-------
first
```

在以下示例中，查询返回字符串 `NULL`，因为字符串文本参数相等。

```
SELECT NULLIF('first', 'first');

case
-------
NULL
```

在以下示例中，查询返回 `1`，因为整数参数不相等。

```
SELECT NULLIF(1, 2);

case
-------
1
```

在以下示例中，查询返回 `NULL`，因为整数参数相等。

```
SELECT NULLIF(1, 1);

case
-------
NULL
```

在以下示例中，查询在 LISTID 和 SALESID 值匹配时返回 null：

```
select nullif(listid,salesid), salesid
from sales where salesid<10 order by 1, 2 desc;

listid  | salesid
--------+---------
     4  |       2
     5  |       4
     5  |       3
     6  |       5
     10 |       9
     10 |       8
     10 |       7
     10 |       6
        |       1
(9 rows)
```

您可以使用 NULLIF 来确保始终将空字符串返回为 null。在以下示例中，NULLIF 表达式返回一个 null 值或一个包含至少一个字符的字符串。

```
insert into category
values(0,'','Special','Special');

select nullif(catgroup,'') from category
where catdesc='Special';

catgroup
----------
null
(1 row)
```

NULLIF 忽略尾随空格。如果一个字符串不为空但包含空格，则 NULLIF 仍返回 null：

```
create table nulliftest(c1 char(2), c2 char(2));

insert into nulliftest values ('a','a ');

insert into nulliftest values ('b','b');


select nullif(c1,c2) from nulliftest;
c1
------
null
null
(2 rows)
```

# 数据类型格式设置函数
<a name="r_Data_type_formatting"></a>

**Topics**
+ [CAST 函数](r_CAST_function.md)
+ [CONVERT 函数](r_CONVERT_function.md)
+ [TEXT\$1TO\$1INT\$1ALT](r_TEXT_TO_INT_ALT.md)
+ [TEXT\$1TO\$1NUMERIC\$1ALT](r_TEXT_TO_NUMERIC_ALT.md)
+ [TO\$1CHAR](r_TO_CHAR.md)
+ [TO\$1DATE 函数](r_TO_DATE_function.md)
+ [TO\$1NUMBER](r_TO_NUMBER.md)
+ [TRY\$1CAST 函数](r_TRY_CAST.md)
+ [日期时间格式字符串](r_FORMAT_strings.md)
+ [数字格式字符串](r_Numeric_formating.md)
+ [数字数据的 Teradata 类格式字符](r_Numeric-format-teradata.md)

数据类型格式设置函数提供了将值从一种数据类型转换为另一种数据类型的简单方式。对于这些函数，第一个参数始终是要进行格式设置的参数，第二个参数包含新格式的模板。Amazon Redshift 支持若干数据类型格式设置函数。

# CAST 函数
<a name="r_CAST_function"></a>

CAST 函数将一种数据类型转换为另一种兼容的数据类型。例如，您可以将字符串转换为日期，或将数值类型转换为字符串。CAST 执行运行时转换，这意味着转换不会更改源表中值的数据类型。仅在查询上下文中对其进行更改。

CAST 函数与 [CONVERT 函数](r_CONVERT_function.md) 非常相似，它们都将一种数据类型转换为另一种数据类型，但它们的调用方式不同。

某些数据类型需要使用 CAST 或 CONVERT 函数显式转换为其他数据类型。其他数据类型可进行隐式转换（作为另一个命令的一部分），无需使用 CAST 或 CONVERT。请参阅[类型兼容性和转换](c_Supported_data_types.md#r_Type_conversion)。

## 语法
<a name="r_CAST_function-syntax"></a>

使用以下两个等效的语法形式，将表达式从一种数据类型强制转换为另一种数据类型。

```
CAST ( expression AS type )
expression :: type
```

## 参数
<a name="r_CAST_function-arguments"></a>

 *expression*   
计算结果为一个或多个值的表达式，如列名称或文本。转换 null 值将返回 null。表达式不能包含空白或空字符串。

 *type*   
支持的 [数据类型](c_Supported_data_types.md) 之一。

## 返回类型
<a name="r_CAST_function-return-type"></a>

CAST 返回 *type* 参数指定的数据类型。

**注意**  
如果您尝试执行有问题的转换（例如，会导致精度损失的 DECIMAL 转换），Amazon Redshift 将返回错误。有问题的转换示例如下：  

```
select 123.456::decimal(2,1);
```
或导致溢出的 INTEGER 转换：  

```
select 12345678::smallint;
```

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

某些示例使用示例 [TICKIT 数据库](https://docs.aws.amazon.com/redshift/latest/dg/c_sampledb.html)。有关设置示例数据的更多信息，请参阅[加载数据](https://docs.aws.amazon.com/redshift/latest/gsg/cm-dev-t-load-sample-data.html)。

以下两个查询是等效的。它们都将小数值转换为整数：

```
select cast(pricepaid as integer)
from sales where salesid=100;

pricepaid
-----------
162
(1 row)
```

```
select pricepaid::integer
from sales where salesid=100;

pricepaid
-----------
162
(1 row)
```

以下内容会产生类似的结果。它不需要示例数据即可运行：

```
select cast(162.00 as integer) as pricepaid;

pricepaid
-----------
162
(1 row)
```

在此示例中，时间戳列中的值将强制转换为日期，这会导致从每个结果中删除时间：

```
select cast(saletime as date), salesid
from sales order by salesid limit 10;

 saletime  | salesid
-----------+---------
2008-02-18 |       1
2008-06-06 |       2
2008-06-06 |       3
2008-06-09 |       4
2008-08-31 |       5
2008-07-16 |       6
2008-06-26 |       7
2008-07-10 |       8
2008-07-22 |       9
2008-08-06 |      10
(10 rows)
```

如果您没有像前一个示例中所示的那样使用 CAST，则结果将包括时间：*2008-02-18 02:36:48*。

以下查询将可变字符数据强制转换为日期。它不需要示例数据即可运行。

```
select cast('2008-02-18 02:36:48' as date) as mysaletime;

mysaletime    
--------------------
2008-02-18  
(1 row)
```

在此示例中，日期列中的值将强制转换为时间戳：

```
select cast(caldate as timestamp), dateid
from date order by dateid limit 10;

      caldate       | dateid
--------------------+--------
2008-01-01 00:00:00 |   1827
2008-01-02 00:00:00 |   1828
2008-01-03 00:00:00 |   1829
2008-01-04 00:00:00 |   1830
2008-01-05 00:00:00 |   1831
2008-01-06 00:00:00 |   1832
2008-01-07 00:00:00 |   1833
2008-01-08 00:00:00 |   1834
2008-01-09 00:00:00 |   1835
2008-01-10 00:00:00 |   1836
(10 rows)
```

在与前面的示例类似的情况下，您可以使用 [TO\$1CHAR](https://docs.aws.amazon.com/redshift/latest/dg/r_TO_CHAR.html) 进一步控制输出格式。

在此示例中，整数将强制转换为字符串：

```
select cast(2008 as char(4));

bpchar
--------
2008
```

在此示例中，DECIMAL(6,3) 值将强制转换为 DECIMAL(4,1) 值：

```
select cast(109.652 as decimal(4,1));

numeric
---------
109.7
```

此示例显示了一个更复杂的表达式。SALES 表中的 PRICEPAID 列（DECIMAL(8,2) 列）将转换为 DECIMAL(38,2) 列，并且值将乘以 100000000000000000000：

```
select salesid, pricepaid::decimal(38,2)*100000000000000000000
as value from sales where salesid<10 order by salesid;


 salesid |           value
---------+----------------------------
       1 | 72800000000000000000000.00
       2 |  7600000000000000000000.00
       3 | 35000000000000000000000.00
       4 | 17500000000000000000000.00
       5 | 15400000000000000000000.00
       6 | 39400000000000000000000.00
       7 | 78800000000000000000000.00
       8 | 19700000000000000000000.00
       9 | 59100000000000000000000.00
(9 rows)
```

**注意**  
无法对 `GEOMETRY` 数据类型执行 CAST 或 CONVERT 操作来将其更改为其他数据类型。不过，您可以提供扩展的已知二进制 (EWKB) 格式的字符串文字的十六进制表示形式，作为接受 `GEOMETRY` 参数的函数的输入。例如，下面的 `ST_AsText` 函数需要 `GEOMETRY` 数据类型。  

```
SELECT ST_AsText('01010000000000000000001C400000000000002040');
```

```
st_astext  
------------
 POINT(7 8)
```
您也可以明确指定 `GEOMETRY` 数据类型。  

```
SELECT ST_AsText('010100000000000000000014400000000000001840'::geometry);
```

```
st_astext  
------------
 POINT(5 6)
```

# CONVERT 函数
<a name="r_CONVERT_function"></a>

与 [CAST 函数](https://docs.aws.amazon.com/redshift/latest/dg/r_CAST_function.html)相似，CONVERT 函数将一种数据类型转换为另一种兼容的数据类型。例如，您可以将字符串转换为日期，或将数值类型转换为字符串。CONVERT 执行运行时转换，这意味着转换不会更改源表中值的数据类型。仅在查询上下文中对其进行更改。

某些数据类型需要使用 CONVERT 函数显式转换为其他数据类型。其他数据类型可进行隐式转换（作为另一个命令的一部分），无需使用 CAST 或 CONVERT。请参阅[类型兼容性和转换](c_Supported_data_types.md#r_Type_conversion)。

## 语法
<a name="r_CONVERT-syntax"></a>

```
CONVERT ( type, expression )
```

## 参数
<a name="r_CONVERT-arguments"></a>

 *type*   
支持的 [数据类型](c_Supported_data_types.md) 之一。

 *expression*   
计算结果为一个或多个值的表达式，如列名称或文本。转换 null 值将返回 null。表达式不能包含空白或空字符串。

## 返回类型
<a name="r_CONVERT-return-type"></a>

CONVERT 返回 *type* 参数指定的数据类型。

**注意**  
如果您尝试执行有问题的转换（例如，会导致精度损失的 DECIMAL 转换），Amazon Redshift 将返回错误。有问题的转换示例如下：  

```
SELECT CONVERT(decimal(2,1), 123.456);
```
或导致溢出的 INTEGER 转换：  

```
SELECT CONVERT(smallint, 12345678);
```

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

某些示例使用示例 [TICKIT 数据库](https://docs.aws.amazon.com/redshift/latest/dg/c_sampledb.html)。有关设置示例数据的更多信息，请参阅[加载数据](https://docs.aws.amazon.com/redshift/latest/gsg/cm-dev-t-load-sample-data.html)。

以下查询使用 CONVERT 函数将一些小数列转换为整数

```
SELECT CONVERT(integer, pricepaid)
FROM sales WHERE salesid=100;
```

此示例将整数转换为字符串。

```
SELECT CONVERT(char(4), 2008);
```

在此示例中，当前日期和时间转换为可变字符数据类型：

```
SELECT CONVERT(VARCHAR(30), GETDATE());

getdate
---------
2023-02-02 04:31:16
```

此示例将 saletime 列仅转换只包括时间，删除每行中的日期。

```
SELECT CONVERT(time, saletime), salesid
FROM sales order by salesid limit 10;
```

有关将时间戳从一个时区转换为另一个时区的信息，请参阅 [CONVERT\$1TIMEZONE 函数](CONVERT_TIMEZONE.md)。有关其他日期和时间函数，请参阅[日期和时间函数](Date_functions_header.md)。

以下示例将可变字符数据转换为日期时间对象。

```
SELECT CONVERT(datetime, '2008-02-18 02:36:48') as mysaletime;
```

**注意**  
无法对 `GEOMETRY` 数据类型执行 CAST 或 CONVERT 操作来将其更改为其他数据类型。不过，您可以提供扩展的已知二进制 (EWKB) 格式的字符串文字的十六进制表示形式，作为接受 `GEOMETRY` 参数的函数的输入。例如，下面的 `ST_AsText` 函数需要 `GEOMETRY` 数据类型。  

```
SELECT ST_AsText('01010000000000000000001C400000000000002040');
```

```
st_astext  
------------
 POINT(7 8)
```
您也可以明确指定 `GEOMETRY` 数据类型。  

```
SELECT ST_AsText('010100000000000000000014400000000000001840'::geometry);
```

```
st_astext  
------------
 POINT(5 6)
```

# TEXT\$1TO\$1INT\$1ALT
<a name="r_TEXT_TO_INT_ALT"></a>

TEXT\$1TO\$1INT\$1ALT 使用 Teradata 类格式将字符串转换为整数。结果中的小数位数将被截断。

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

```
TEXT_TO_INT_ALT (expression [ , 'format'])
```

## 参数
<a name="r_TEXT_TO_INT_ALT-arguments"></a>

 *expression*   
结果产生一个或多个 CHAR 或 VARCHAR 值的表达式，如列名称或文本字符串。转换 null 值将返回 null。该函数将空白或空字符串转换为 0。

 *format*   
一个字符串文本，用于定义输入表达式的格式。有关您可以指定的格式字符的更多信息，请参阅[数字数据的 Teradata 类格式字符](r_Numeric-format-teradata.md)。

## 返回类型
<a name="r_TEXT_TO_INT_ALT-return-type"></a>

TEXT\$1TO\$1INT\$1ALT 返回一个 INTEGER 值。

转换结果的小数部分将被截断。

如果转换为您指定的 *format* 短语不成功，Amazon Redshift 将返回一个错误。

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

以下示例将输入 *expression* 字符串“123-”转换为整数 -123。

```
select text_to_int_alt('123-');
```

```
text_to_int_alt
----------
      -123
```

以下示例将输入 *expression* 字符串“2147483647\$1”转换为整数 2147483647。

```
select text_to_int_alt('2147483647+');
```

```
text_to_int_alt
----------
2147483647
```

以下示例将指数输入 *expression* 字符串“-123E-2”转换为整数 -1。

```
select text_to_int_alt('-123E-2');
```

```
text_to_int_alt
----------
        -1
```

以下示例将输入 *expression* 字符串“2147483647\$1”转换为整数 2147483647。

```
select text_to_int_alt('2147483647+');
```

```
text_to_int_alt
----------
2147483647
```

以下示例使用 *format* 短语“999S”将输入 *expression* 字符串“123\$1”转换为整数 1230。S 字符表示带符号的分区十进制。有关更多信息，请参阅 [数字数据的 Teradata 类格式字符](r_Numeric-format-teradata.md)。

```
select text_to_int_alt('123{', '999S');
```

```
text_to_int_alt
----------
      1230
```

以下示例使用 *format* 短语“C9(I)”将输入 *expression* 字符串“USD123”转换为整数 123。请参阅 [数字数据的 Teradata 类格式字符](r_Numeric-format-teradata.md)。

```
select text_to_int_alt('USD123', 'C9(I)');
```

```
text_to_int_alt
----------
       123
```

以下示例指定一个表列作为输入 *expression*。

```
select text_to_int_alt(a), text_to_int_alt(b) from t_text2int order by 1;
```

```
 text_to_int_alt | text_to_int_alt
-----------------+-----------------
            -123 |            -123
            -123 |            -123
             123 |             123
             123 |             123
```

以下是此示例的表定义和 insert 语句。

```
create table t_text2int (a varchar(200), b char(200));
```

```
insert into t_text2int VALUES('123', '123'),('123.123', '123.123'), ('-123', '-123'), ('123-', '123-');
```

# TEXT\$1TO\$1NUMERIC\$1ALT
<a name="r_TEXT_TO_NUMERIC_ALT"></a>

TEXT\$1TO\$1NUMERIC\$1ALT 执行一种 Teradata 类的转换操作，以将字符串转换为数字数据格式。

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

```
TEXT_TO_NUMERIC_ALT (expression [, 'format'] [, precision, scale])
```

## 参数
<a name="r_TEXT_TO_NUMERIC_ALT-arguments"></a>

 *expression*   
计算结果为一个或多个 CHAR 或 VARCHAR 值的表达式，如列名称或文本。转换 null 值将返回 null。空白或空字符串将转换为 0。

 *format*   
一个字符串文本，用于定义输入表达式的格式。有关更多信息，请参阅 [数字数据的 Teradata 类格式字符](r_Numeric-format-teradata.md)。

 *精度*   
数字结果中的位数。默认值为 38。

 *小数位数*   
数字结果中小数点右侧的位数。默认值为 0。

## 返回类型
<a name="r_TEXT_TO_NUMERIC_ALT-return-type"></a>

TEXT\$1TO\$1NUMERIC\$1ALT 返回一个 DECIMAL 数。

如果转换为您指定的 *format* 短语不成功，Amazon Redshift 将返回一个错误。

Amazon Redshift 使用您在*精度*选项中为该类型指定的最高精度将输入 *expression* 字符串转换为数字类型。如果数值的长度超过您为*精度*指定的值，Amazon Redshift 将根据以下规则对数值进行四舍五入：
+ 如果转换结果的长度超出了您在 *format* 短语中指定的长度，Amazon Redshift 会返回一个错误。
+ 如果将结果转换为数值，则结果将四舍五入到最接近的值。如果小数部分正好位于上下转换结果的中间位置，则结果将四舍五入到最接近的偶数值。

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

以下示例将输入 *expression* 字符串“1.5”转换为数值“2”。因为语句没有指定*小数位数*，*小数位数*默认值为 0，并且转换结果不包含分数结果。因为 .5 介于 1 和 2 之间的中间，所以转换结果四舍五入为偶数值 2。

```
select text_to_numeric_alt('1.5');
```

```
 text_to_numeric_alt
---------------------
                   2
```

以下示例将输入 *expression* 字符串“2.51”转换为数值 3。因为语句没有指定*小数位数*，*小数位数*默认值为 0，并且转换结果不包含分数结果。因为 .51 接近 3 而不是 2，所以转换结果四舍五入到值 3。

```
select text_to_numeric_alt('2.51');
```

```
 text_to_numeric_alt
---------------------
                   3
```

以下示例以 10 为*精度*，2 为*小数位数*，将输入 *expression* 字符串 123.52501 转换为数值 123.53。

```
select text_to_numeric_alt('123.52501', 10, 2);
```

```
 text_to_numeric_alt
---------------------
               123.53
```

以下示例使用 *format* 短语“999S”将输入 *expression* 字符串“123\$1”转换为数值 1230。S 字符表示带符号的分区十进制。有关更多信息，请参阅 [数字数据的 Teradata 类格式字符](r_Numeric-format-teradata.md)。

```
select text_to_numeric_alt('123{', '999S');
```

```
text_to_int_alt
----------
      1230
```

以下示例使用 *format* 短语“C9(I)”将输入 *expression* 字符串“USD123”转换为数值 124。请参阅[数字数据的 Teradata 类格式字符](r_Numeric-format-teradata.md)。

```
select text_to_numeric_alt('USD123.9', 'C9(I)');
```

```
text_to_numeric_alt
----------
       124
```

以下示例指定一个表列作为输入 *expression*。

```
select text_to_numeric_alt(a), text_to_numeric_alt(b) from t_text2numeric order by 1;
```

```
           text_to_numeric_alt           |           text_to_numeric_alt
-----------------------------------------+-----------------------------------------
 -99999999999999999999999999999999999999 | -99999999999999999999999999999999999999
                                  -12300 |                                  -12300
                                     123 |                                     123
                                     123 |                                     123
  99999999999999999999999999999999999999 |  99999999999999999999999999999999999999
```

以下是此示例的表定义和 insert 语句。

```
create table  t_text2numeric (a varchar(200), b char(200));
```

```
insert into  t_text2numeric values
('123', '123'),
('+123.456', '+123.456'),
('-' || repeat('9', 38), '-' || repeat('9', 38)),
(repeat('9', 38) || '+', repeat('9', 38) || '+'),
('-123E2', '-123E2');
```

# TO\$1CHAR
<a name="r_TO_CHAR"></a>

TO\$1CHAR 将时间戳或数值表达式转换为字符串数据格式。

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

```
TO_CHAR (timestamp_expression | numeric_expression , 'format')
```

## 参数
<a name="r_TO_CHAR-arguments"></a>

 *timestamp\$1expression*   
一个表达式，用于生成 TIMESTAMP 或 TIMESTAMPTZ 类型值或可隐式强制转换为时间戳的值。

 *numeric\$1expression*   
一个表达式，用于生成数字数据类型值或可隐式强制转换为数字类型的值。有关更多信息，请参阅 [数字类型](r_Numeric_types201.md)。TO\$1CHAR 在数字串左侧插入空格。  
TO\$1CHAR 不支持 128 位 DECIMAL 值。

 *format*   
新值的格式。有关有效格式，请参阅[日期时间格式字符串](r_FORMAT_strings.md)和[数字格式字符串](r_Numeric_formating.md)。

## 返回类型
<a name="r_TO_CHAR-return-type"></a>

VARCHAR

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

以下示例将时间戳转换为一个具有日期和时间的值，格式为月份名称填充为九个字符、星期几的名称和当月的日期编号。

```
select to_char(timestamp '2009-12-31 23:15:59', 'MONTH-DY-DD-YYYY HH12:MIPM');

to_char
-------------------------
DECEMBER -THU-31-2009 11:15PM
```

以下示例将时间戳转换为具有这一年中日期编号的值。

```
select to_char(timestamp '2009-12-31 23:15:59', 'DDD');

to_char
-------------------------
365
```

以下示例将时间戳转换为这一周的 ISO 日期编号。

```
select to_char(timestamp '2022-05-16 23:15:59', 'ID');

to_char
-------------------------
1
```

以下示例从日期中提取月份名称。

```
select to_char(date '2009-12-31', 'MONTH');

to_char
-------------------------
DECEMBER
```

以下示例将 EVENT 表中的每个 STARTTIME 值转换为由小时、分钟和秒组成的字符串。

```
select to_char(starttime, 'HH12:MI:SS')
from event where eventid between 1 and 5
order by eventid;

to_char
----------
02:30:00
08:00:00
02:30:00
02:30:00
07:00:00
```

以下示例将整个时间戳值转换为不同的格式。

```
select starttime, to_char(starttime, 'MON-DD-YYYY HH12:MIPM')
from event where eventid=1;

      starttime      |       to_char
---------------------+---------------------
 2008-01-25 14:30:00 | JAN-25-2008 02:30PM
```

以下示例将时间戳文本转换为字符串。

```
select to_char(timestamp '2009-12-31 23:15:59','HH24:MI:SS');

to_char
----------
23:15:59
```

以下示例将十进制数转换为字符串。

```
select to_char(125.8, '999.99');

to_char
---------
125.80
```

以下示例将十进制数转换为字符串。

```
select to_char(125.8, '999D99');

to_char
---------
125.80
```

以下示例将数字转换为具有一个前导零的字符串。

```
select to_char(125.8, '0999D99');

to_char
---------
0125.80
```

以下示例将一个数字转换为末尾带负号的字符串。

```
select to_char(-125.8, '999D99S');

to_char
---------
125.80-
```

以下示例将数字转换为在指定位置带有正号或负号的字符串。

```
select to_char(125.8, '999D99SG');

to_char
---------
125.80+
```

以下示例将数字转换为在指定位置带有正号的字符串。

```
select to_char(125.8, 'PL999D99');

to_char
---------
+ 125.80
```

以下示例将一个数字转换为带货币符号的字符串。

```
select to_char(-125.88, '$S999D99');

to_char
---------
$-125.88
```

以下示例将数字转换为在指定位置带货币符号的字符串。

```
select to_char(-125.88, 'S999D99L');

to_char
---------
-125.88$
```

以下示例使用千位（逗号）分隔符将数字转换为字符串。

```
select to_char(1125.8, '9,999.99');

to_char
---------
1,125.80
```

以下示例将一个数字转换为用尖括号将负数括起来的字符串。

```
select to_char(-125.88, '$999D99PR');

to_char
---------
$<125.88>
```

以下示例将一个数字转换为罗马数字字符串。

```
select to_char(125, 'RN');

to_char
---------
   CXXV
```

以下示例将日期转换为世纪代码。

```
select to_char(date '2020-12-31', 'CC');

to_char
---------
21
```

以下示例显示一周中的某天。

```
SELECT to_char(current_timestamp, 'FMDay, FMDD HH12:MI:SS');

to_char
-----------------------
Wednesday, 31 09:34:26
```

以下示例显示数字的序数后缀。

```
SELECT to_char(482, '999th');

to_char
-----------------------
 482nd
```

以下示例将销售表中支付的价格减去佣金。差随后将向上舍入并转换为罗马数字，如 to\$1char 列中所示：

```
select salesid, pricepaid, commission, (pricepaid - commission)
as difference, to_char(pricepaid - commission, 'rn') from sales
group by sales.pricepaid, sales.commission, salesid
order by salesid limit 10;

 salesid | pricepaid | commission | difference |     to_char
---------+-----------+------------+------------+-----------------
       1 |    728.00 |     109.20 |     618.80 |           dcxix
       2 |     76.00 |      11.40 |      64.60 |             lxv
       3 |    350.00 |      52.50 |     297.50 |        ccxcviii
       4 |    175.00 |      26.25 |     148.75 |           cxlix
       5 |    154.00 |      23.10 |     130.90 |           cxxxi
       6 |    394.00 |      59.10 |     334.90 |         cccxxxv
       7 |    788.00 |     118.20 |     669.80 |           dclxx
       8 |    197.00 |      29.55 |     167.45 |          clxvii
       9 |    591.00 |      88.65 |     502.35 |             dii
      10 |     65.00 |       9.75 |      55.25 |              lv
```

以下示例向 to\$1char 列中显示的差值添加货币符号：

```
select salesid, pricepaid, commission, (pricepaid - commission)
as difference, to_char(pricepaid - commission, 'l99999D99') from sales
group by sales.pricepaid, sales.commission, salesid
order by salesid limit 10;

salesid | pricepaid | commission | difference |  to_char
--------+-----------+------------+------------+------------
      1 |    728.00 |     109.20 |     618.80 | $   618.80
      2 |     76.00 |      11.40 |      64.60 | $    64.60
      3 |    350.00 |      52.50 |     297.50 | $   297.50
      4 |    175.00 |      26.25 |     148.75 | $   148.75
      5 |    154.00 |      23.10 |     130.90 | $   130.90
      6 |    394.00 |      59.10 |     334.90 | $   334.90
      7 |    788.00 |     118.20 |     669.80 | $   669.80
      8 |    197.00 |      29.55 |     167.45 | $   167.45
      9 |    591.00 |      88.65 |     502.35 | $   502.35
     10 |     65.00 |       9.75 |      55.25 | $    55.25
```

以下示例列出了完成每次销售的世纪。

```
select salesid, saletime, to_char(saletime, 'cc') from sales
order by salesid limit 10;

 salesid |      saletime       | to_char
---------+---------------------+---------
       1 | 2008-02-18 02:36:48 | 21
       2 | 2008-06-06 05:00:16 | 21
       3 | 2008-06-06 08:26:17 | 21
       4 | 2008-06-09 08:38:52 | 21
       5 | 2008-08-31 09:17:02 | 21
       6 | 2008-07-16 11:59:24 | 21
       7 | 2008-06-26 12:56:06 | 21
       8 | 2008-07-10 02:12:36 | 21
       9 | 2008-07-22 02:23:17 | 21
      10 | 2008-08-06 02:51:55 | 21
```

以下示例将 EVENT 表中的每个 STARTTIME 值转换为由小时、分钟、秒和时区组成的字符串：

```
select to_char(starttime, 'HH12:MI:SS TZ')
from event where eventid between 1 and 5
order by eventid;

to_char
----------
02:30:00 UTC
08:00:00 UTC
02:30:00 UTC
02:30:00 UTC
07:00:00 UTC
```

以下示例显示了秒、毫秒和微秒的格式设置。

```
select sysdate,
to_char(sysdate, 'HH24:MI:SS') as seconds,
to_char(sysdate, 'HH24:MI:SS.MS') as milliseconds,
to_char(sysdate, 'HH24:MI:SS:US') as microseconds;

timestamp           | seconds  | milliseconds | microseconds   
--------------------+----------+--------------+----------------
2015-04-10 18:45:09 | 18:45:09 | 18:45:09.325 | 18:45:09:325143
```

# TO\$1DATE 函数
<a name="r_TO_DATE_function"></a>

TO\$1DATE 会将以字符串形式表示的日期转换为 DATE 数据类型。

**注意**  
TO\$1DATE 不支持带有 Q（季度编号）的格式字符串。

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

```
TO_DATE(string, format)
```

```
TO_DATE(string, format, is_strict)
```

## 参数
<a name="r_TO_DATE_function-arguments"></a>

 *string*   
要转换的字符串。

 *format*   
一个字符串文本，用于定义其日期部分中的输入*字符串*格式。有关有效日期、月份和年份格式的列表，请参阅[日期时间格式字符串](r_FORMAT_strings.md)。

 *is\$1strict*   
一个可选的布尔值，它指定在输入日期值超出范围时是否返回错误。当 *is\$1strict* 被设置为 `TRUE` 时，如果存在超出范围的值，则返回错误。当 *is\$1strict* 被设置为 `FALSE`（默认值）时，则接受溢出值。

## 返回类型
<a name="r_TO_DATE_function-return-type"></a>

TO\$1DATE 将根据 *format* 值返回 DATE。

如果转换为*格式* 失败，则返回错误。

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

 以下 SQL 语句将日期 `02 Oct 2001` 转换为日期数据类型。

```
select to_date('02 Oct 2001', 'DD Mon YYYY');

to_date
------------
2001-10-02
(1 row)
```

 以下 SQL 语句将字符串 `20010631` 转换为日期。

```
select to_date('20010631', 'YYYYMMDD', FALSE);
```

结果是 2001 年 7 月 1 日，因为六月份只有 30 天。

```
to_date
------------
2001-07-01
```

 以下 SQL 语句将字符串 `20010631` 转换为日期：

```
to_date('20010631', 'YYYYMMDD', TRUE);
```

结果产生错误，因为 6 月只有 30 天。

```
ERROR:  date/time field date value out of range: 2001-6-31
```

# TO\$1NUMBER
<a name="r_TO_NUMBER"></a>

TO\$1NUMBER 将字符串转换为数字（小数）值。

**注意**  
我们建议您在格式字符串中使用 `FM` 来禁止填补空格和零。有关有效格式的列表，请参阅[数字格式字符串](r_Numeric_formating.md)。

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

```
to_number(string, format)
```

## 参数
<a name="r_TO_NUMBER-arguments"></a>

 *string*   
要转换的字符串。格式必须是文本值。

 *format*   
第二个参数是指示应如何分析字符串以创建数字值的格式字符串。例如，格式 `'FM99D999'` 指定要转换的字符串包含五位数，其中小数点在第三位。例如，`to_number('12.345','FM99D999')` 将 `12.345` 作为数字值返回。有关有效格式的列表，请参阅[数字格式字符串](r_Numeric_formating.md)。

## 返回类型
<a name="r_TO_NUMBER-return-type"></a>

TO\$1NUMBER 返回 DECIMAL 数。

如果转换为*格式* 失败，则返回错误。

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

以下示例将字符串 `12,454.8-` 转换为数字：

```
select to_number('12,454.8-', 'FM99G999D9S');

to_number
-----------
-12454.8
```

以下示例将字符串 `$ 12,454.88` 转换为数字：

```
select to_number('$ 12,454.88', 'FML99G999D99');

to_number
-----------
12454.88
```

以下示例将字符串 `$ 2,012,454.88` 转换为数字：

```
select to_number('$ 2,012,454.88', 'FML9,999,999.99');

to_number
-----------
2012454.88
```

# TRY\$1CAST 函数
<a name="r_TRY_CAST"></a>

与 CAST 函数相比，TRY\$1CAST 首先尝试将表达式强制转换为指定的类型。如果强制转换由于转换错误而失败，该操作将返回 null。如果未显式允许强制转换，该操作会返回错误。您可以在下面的使用说明中找到可能的转换列表。例如，不允许尝试将布尔值转换为时间戳。

## 语法
<a name="r_TRY_CAST-syntax"></a>

```
TRY_CAST(expression AS type)
```

## 参数
<a name="r_TRY_CAST-arguments"></a>

 *expression*   
计算结果为一个或多个值的表达式，如列名称或文本。转换 null 值将返回 null。表达式不能包含空白或空字符串。

 *type*   
 受支持的数据类型之一。有关数据类型的完全列表，请参阅[数据类型](c_Supported_data_types.md)。有关受支持的源数据类型和目标数据类型对的列表，请参阅下面的使用说明。

## 返回类型
<a name="r_TRY_CAST-return-type"></a>

TRY\$1CAST 返回由 *type* 参数指定的数据类型的值。如果转换失败，该操作将返回 null。

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

以下是 Amazon Redshift 针对 TRY\$1CAST 支持的源数据类型和目标数据类型对的列表。

 *BOOL*   
 SMALLINT、INT、BIGINT、SUPER 

 *SMALLINT*   
 BOOL、INT、BIGINT、DECIMAL、REAL、FLOAT、BPCHAR、TEXT、VARCHAR、SUPER 

 *INT*   
 BOOL、SMALLINT、BIGINT、DECIMAL、REAL、FLOAT、BPCHAR、TEXT、VARCHAR、SUPER 

 *BIGINT*   
 BOOL、SMALLINT、INT、DECIMAL、REAL、FLOAT、BPCHAR、TEXT、VARCHAR、SUPER 

 *DECIMAL*   
 SMALLINT、INT、BIGINT、REAL、FLOAT、BPCHAR、TEXT、VARCHAR、SUPER 

 *REAL*   
 SMALLINT、INT、BIGINT、DECIMAL、FLOAT、BPCHAR、TEXT、VARCHAR、SUPER 

 *FLOAT*   
 SMALLINT、INT、BIGINT、DECIMAL、REAL、BPCHAR、TEXT、VARCHAR、SUPER 

 *BPCHAR*   
 SMALLINT、INT、BIGINT、DECIMAL、REAL、FLOAT、TEXT、VARCHAR、TIMESTAMP、TIMESTAMPTZ、DATE、TIME、TIMETZ、SUPER 

 *TEXT*   
 SMALLINT、INT、BIGINT、DECIMAL、REAL、FLOAT、BPCHAR、VARCHAR、TIMESTAMP、TIMESTAMPTZ、DATE、TIME、TIMETZ、SUPER 

 *VARCHAR*   
 SMALLINT、INT、BIGINT、DECIMAL、REAL、FLOAT、BPCHAR、TEXT、TIMESTAMP、TIMESTAMPTZ、DATE、TIME、TIMETZ、SUPER 

 *TIMESTAMP*   
 BPCHAR、TEXT、VARCHAR、TIMESTAMPTZ、DATE、TIME 

 *TIMESTAMPTZ*   
 BPCHAR、TEXT、VARCHAR、TIMESTAMP、DATE、TIME、TIMETZ 

 *DATE*   
 BPCHAR、TEXT、VARCHAR、TIMESTAMP、TIMESTAMPTZ 

 *TIME*   
 BPCHAR、TEXT、VARCHAR 

 *TIMETZ*   
 BPCHAR、TEXT、VARCHAR 

 *SUPER*   
 SUPER 可以转换为任何其它数据类型，但 DATE、TIME、TIMETZ、TIMESTAMP 和 TIMESTAMPTZ 除外。

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

以下示例将 STRING 强制转换为 INTEGER。

```
SELECT TRY_CAST('123' AS INT);

int
----
123
```

以下示例返回 null。允许将 STRING 转换为 INTEGER，因此 TRY\$1CAST 不会返回错误，但是“foo”不是整数，因此该函数返回 null。

```
SELECT TRY_CAST('foo' AS INT)
```

以下示例返回错误，因为不允许将 BOOLEAN 转换为 TIMESTAMP。

```
SELECT TRY_CAST(true as timestamp);
```

由于 TRY\$1CAST 返回 null，而不是在转换失败时立即返回错误，因此您可以使用 TRY\$1CAST 筛选掉无效数据。请考虑以下示例，其中由于 Akua Mansa 的 age 列中存在转换失败，因此筛选掉了无效行。

```
CREATE TABLE IF NOT EXISTS student_data(
name VARCHAR(100) NOT NULL,
age VARCHAR(3) NOT NULL,
enrollment_date DATE NOT NULL);

INSERT INTO student_data (name, age, enrollment_date)
VALUES
('Alejandro Rosalez', '10', '01/01/2000'),
('Akua Mansa', 'Ten', '01/01/2000');

SELECT * FROM student_data WHERE TRY_CAST(age AS INT) IS NOT NULL;

--Akua is not returned.
 name              | age | enrollment_date
-------------------+-----+-----------------
 Alejandro Rosalez | 10  | 01/01/2000
```

# 日期时间格式字符串
<a name="r_FORMAT_strings"></a>

您可以找到日期时间格式字符串遵循的引用。

以下格式字符串适用于 TO\$1CHAR 之类的函数。这些字符串可包含日期时间分隔符（如 '`-`'、'`/`' 或 '`:`'）以及下面的日期部分和时间部分。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_FORMAT_strings.html)

**注意**  
您必须用单引号将 datetime 分隔符（如 '-'、'/' 或 ':'）括起，但您必须用双引号将上表中列出的 "dateparts" 和 "timeparts" 括起。

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

有关将日期格式化为字符串的示例，请参阅[TO\$1CHAR](r_TO_CHAR.md)。

# 数字格式字符串
<a name="r_Numeric_formating"></a>

在下面，您可以找到数字格式字符串的引用。

以下格式字符串适用于 TO\$1NUMBER 和 TO\$1CHAR 之类的函数。
+ 有关将字符串格式化为数字的示例，请参阅[TO\$1NUMBER](r_TO_NUMBER.md)。
+ 有关将数字格式化为字符串的示例，请参阅[TO\$1CHAR](r_TO_CHAR.md)。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Numeric_formating.html)

# 数字数据的 Teradata 类格式字符
<a name="r_Numeric-format-teradata"></a>

下面，您可以找到 TEXT\$1TO\$1INT\$1ALT 和 TEXT\$1TO\$1NUMERIC\$1ALT 函数如何解释输入 *expression* 字符串中的字符。您还可以找到您可以在 *format* 短语中指定的字符列表。此外，您还可以找到 Teradata 类格式和 Amazon Redshift 之间的*格式*选项差异的说明。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Numeric-format-teradata.html)

## 带符号的分区十进制、Teradata 类数字数据格式的数据格式字符
<a name="r_Numeric-format-teradata-signed-zone"></a>

您可以在 TEXT\$1TO\$1INT\$1ALT 和 TEXT\$1TO\$1NUMERIC\$1ALT 函数的 *format* 短语中将以下字符用于带符号的分区十进制值。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Numeric-format-teradata.html)

# 日期和时间函数
<a name="Date_functions_header"></a>

在本部分中，您可以找到 Amazon Redshift 支持的日期和时间标量函数的相关信息。

**Topics**
+ [日期和时间函数摘要](#date-functions-summary)
+ [事务中的日期和时间函数](#date-functions-transactions)
+ [弃用的仅领导节点函数](#date-functions-deprecated)
+ [\$1（串联）运算符](r_DATE-CONCATENATE_function.md)
+ [ADD\$1MONTHS 函数](r_ADD_MONTHS.md)
+ [AT TIME ZONE 函数](r_AT_TIME_ZONE.md)
+ [CONVERT\$1TIMEZONE 函数](CONVERT_TIMEZONE.md)
+ [CURRENT\$1DATE 函数](r_CURRENT_DATE_function.md)
+ [DATE\$1CMP 函数](r_DATE_CMP.md)
+ [DATE\$1CMP\$1TIMESTAMP 函数](r_DATE_CMP_TIMESTAMP.md)
+ [DATE\$1CMP\$1TIMESTAMPTZ 函数](r_DATE_CMP_TIMESTAMPTZ.md)
+ [DATEADD 函数](r_DATEADD_function.md)
+ [DATEDIFF 函数](r_DATEDIFF_function.md)
+ [DATE\$1PART 函数](r_DATE_PART_function.md)
+ [DATE\$1PART\$1YEAR 函数](r_DATE_PART_YEAR.md)
+ [DATE\$1TRUNC 函数](r_DATE_TRUNC.md)
+ [EXTRACT 函数](r_EXTRACT_function.md)
+ [GETDATE 函数](r_GETDATE.md)
+ [INTERVAL\$1CMP 函数](r_INTERVAL_CMP.md)
+ [LAST\$1DAY 函数](r_LAST_DAY.md)
+ [MONTHS\$1BETWEEN 函数](r_MONTHS_BETWEEN_function.md)
+ [NEXT\$1DAY 函数](r_NEXT_DAY.md)
+ [SYSDATE 函数](r_SYSDATE.md)
+ [TIMEOFDAY 函数](r_TIMEOFDAY_function.md)
+ [TIMESTAMP\$1CMP 函数](r_TIMESTAMP_CMP.md)
+ [TIMESTAMP\$1CMP\$1DATE 函数](r_TIMESTAMP_CMP_DATE.md)
+ [TIMESTAMP\$1CMP\$1TIMESTAMPTZ 函数](r_TIMESTAMP_CMP_TIMESTAMPTZ.md)
+ [TIMESTAMPTZ\$1CMP 函数](r_TIMESTAMPTZ_CMP.md)
+ [TIMESTAMPTZ\$1CMP\$1DATE 函数](r_TIMESTAMPTZ_CMP_DATE.md)
+ [TIMESTAMPTZ\$1CMP\$1TIMESTAMP 函数](r_TIMESTAMPTZ_CMP_TIMESTAMP.md)
+ [TIMEZONE 函数](r_TIMEZONE.md)
+ [TO\$1TIMESTAMP 函数](r_TO_TIMESTAMP.md)
+ [TRUNC 函数](r_TRUNC_date.md)
+ [日期或时间戳函数的日期部分](r_Dateparts_for_datetime_functions.md)

## 日期和时间函数摘要
<a name="date-functions-summary"></a>

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/Date_functions_header.html)

**注意**  
在经过时间计算中不考虑闰秒。

## 事务中的日期和时间函数
<a name="date-functions-transactions"></a>

当您在事务块（BEGIN … END）中运行以下函数时，该函数将返回当前事务的开始日期或时间，而不是当前语句的开始时间。
+ SYSDATE
+ TIMESTAMP
+ CURRENT\$1DATE

以下函数始终返回当前语句的开始日期或时间，即使它们在事务数据块中也是如此。
+ GETDATE
+ TIMEOFDAY

## 弃用的仅领导节点函数
<a name="date-functions-deprecated"></a>

以下日期函数因为仅在领导节点上运行而遭到弃用。有关更多信息，请参阅 [仅领导节点函数](c_SQL_functions_leader_node_only.md)。
+ AGE。请改用 [DATEDIFF 函数](r_DATEDIFF_function.md)。
+ CURRENT\$1TIME。改用 [GETDATE 函数](r_GETDATE.md) 或 [SYSDATE](r_SYSDATE.md)。
+ CURRENT\$1TIMESTAMP。改用 [GETDATE 函数](r_GETDATE.md) 或 [SYSDATE](r_SYSDATE.md)。
+ LOCALTIME。改用 [GETDATE 函数](r_GETDATE.md) 或 [SYSDATE](r_SYSDATE.md)。
+ LOCALTIMESTAMP。改用 [GETDATE 函数](r_GETDATE.md) 或 [SYSDATE](r_SYSDATE.md)。
+ ISFINITE 
+ NOW。改用 [GETDATE 函数](r_GETDATE.md) 或 [SYSDATE](r_SYSDATE.md)。如果在实体化视图中使用 NOW 函数，则它将设置为创建实体化视图的时间戳，而不是当前的时间戳。

# \$1（串联）运算符
<a name="r_DATE-CONCATENATE_function"></a>

将 DATE 连接到 \$1 符号任一侧的 TIME 或 TIMETZ，并返回 TIMESTAMP 或 TIMESTAMPTZ。

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

```
date + {time | timetz}
```

参数的顺序可以反转。例如，*time* \$1 *date*。

## 参数
<a name="r_DATE-CONCATENATE_function-arguments"></a>

 *date*   
数据类型为 `DATE` 的列，或一个隐式计算结果为 `DATE` 类型的表达式。

 *时间*   
数据类型为 `TIME` 的列，或一个隐式计算结果为 `TIME` 类型的表达式。

 *timetz*   
数据类型为 `TIMETZ` 的列，或一个隐式计算结果为 `TIMETZ` 类型的表达式。

## 返回类型
<a name="r_DATE-CONCATENATE_function-return-type"></a>

如果输入为 *date* \$1 *time*，则为 TIMESTAMP。

如果输入为 *date* \$1 *timetz*，则为 TIMESTAMPTZ。

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

### 示例设置
<a name="r_DATE-CONCATENATE_function-example-setup"></a>

要设置示例中使用的 TIME\$1TEST 和 TIMETZ\$1TEST 表，请使用以下命令。

```
create table time_test(time_val time);

insert into time_test values
('20:00:00'),
('00:00:00.5550'),
('00:58:00');
   
create table timetz_test(timetz_val timetz);
   
insert into timetz_test values
('04:00:00+00'),
('00:00:00.5550+00'),
('05:58:00+00');
```

### 具有时间列的示例
<a name="r_DATE-CONCATENATE_function-examples-time"></a>

下面的示例表 TIME\$1TEST 具有一个列 TIME\$1VAL（类型 TIME），其中插入了三个值。

```
select time_val from time_test;
            
time_val
---------------------
20:00:00
00:00:00.5550
00:58:00
```

以下示例串联一个日期文本和一个 TIME\$1VAL 列。

```
select date '2000-01-02' + time_val as ts from time_test;
            
ts
---------------------
2000-01-02 20:00:00
2000-01-02 00:00:00.5550
2000-01-02 00:58:00
```

以下示例串联一个日期文本和一个时间文本。

```
select date '2000-01-01' + time '20:00:00' as ts;
            
         ts
---------------------
 2000-01-01 20:00:00
```

以下示例串联一个时间文本和一个日期文本。

```
select time '20:00:00' + date '2000-01-01' as ts;
            
         ts
---------------------
 2000-01-01 20:00:00
```

### 具有 TIMETZ 列的示例
<a name="r_DATE-CONCATENATE_function-examples-timetz"></a>

下面的示例表 TIMETZ\$1TEST 具有一个列 TIMETZ\$1VAL（类型 TIMETZ），其中插入了三个值。

```
select timetz_val from timetz_test;
            
timetz_val
------------------
04:00:00+00
00:00:00.5550+00
05:58:00+00
```

以下示例串联一个日期文本和一个 TIMETZ\$1VAL 列。

```
select date '2000-01-01' + timetz_val as ts from timetz_test;
ts
---------------------
2000-01-01 04:00:00+00
2000-01-01 00:00:00.5550+00
2000-01-01 05:58:00+00
```

以下示例串联一个 TIMETZ\$1VAL 列和一个日期文本。

```
select timetz_val + date '2000-01-01' as ts from timetz_test;
ts
---------------------
2000-01-01 04:00:00+00
2000-01-01 00:00:00.5550+00
2000-01-01 05:58:00+00
```

以下示例串联一个 DATE 文本和一个 TIMETZ 文本。该示例返回 TIMESTAMPTZ，默认情况下它采用 UTC 时区。UTC 比 PST 早 8 小时，因此结果比输入时间早 8 小时。

```
select date '2000-01-01' + timetz '20:00:00 PST' as ts;
            
           ts
------------------------
 2000-01-02 04:00:00+00
```

# ADD\$1MONTHS 函数
<a name="r_ADD_MONTHS"></a>

ADD\$1MONTHS 会将指定的月数添加到日期或时间戳值或表达式中。[DATEADD](r_DATEADD_function.md) 函数提供了类似的功能。

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

```
ADD_MONTHS( {date | timestamp}, integer)
```

## 参数
<a name="r_ADD_MONTHS-arguments"></a>

 *date* \$1 *timestamp*   
数据类型为 `DATE` 或 `TIMESTAMP` 的列，或一个隐式计算结果为 `DATE` 或 `TIMESTAMP` 类型的表达式。如果日期是该月的最后一天，或者如果产生的月份较短，则函数在结果中返回该月的最后一天。对于其他日期，结果包含与日期表达式相同的日期编号。

 *integer*   
数据类型 `INTEGER` 的值。使用负数从日期中减去月份。

## 返回类型
<a name="r_ADD_MONTHS-return-type"></a>

TIMESTAMP

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

以下查询使用 TRUNC 函数内的 ADD\$1MONTHS 函数。TRUNC 函数从 ADD\$1MONTHS 的结果中删除一天中的时间。ADD\$1MONTHS 函数会为 CALDATE 列中的每个值添加 12 个月。CALDATE 列中的值是日期。

```
select distinct trunc(add_months(caldate, 12)) as calplus12,
trunc(caldate) as cal
from date
order by 1 asc;

 calplus12  |    cal
------------+------------
 2009-01-01 | 2008-01-01
 2009-01-02 | 2008-01-02
 2009-01-03 | 2008-01-03
...
(365 rows)
```

以下示例使用 ADD\$1MONTHS 函数给*时间戳* 加上 1 个月。

```
select add_months('2008-01-01 05:07:30', 1); 

add_months
---------------------
2008-02-01 05:07:30
```

以下示例演示 ADD\$1MONTHS 函数在具有不同天数的月份的日期上运行时的行为。此示例说明该函数如何处理在 3 月 31 日的基础上再加上 1 个月以及在 4 月 30 日的基础上再加上 1 个月的情况。4 月有 30 天，所以在 3 月 31 日的基础上再加上 1 个月，结果是 4 月 30 日。5 月有 31 天，所以在 4 月 30 日的基础上再加上 1 个月，结果是 5 月 31 日。

```
select add_months('2008-03-31',1);

add_months
---------------------
2008-04-30 00:00:00

select add_months('2008-04-30',1); 

add_months
---------------------
2008-05-31 00:00:00
```

# AT TIME ZONE 函数
<a name="r_AT_TIME_ZONE"></a>

AT TIME ZONE 指定要与 TIMESTAMP 或 TIMESTAMPTZ 表达式一起使用的时区。

## 语法
<a name="r_AT_TIME_ZONE-syntax"></a>

```
AT TIME ZONE 'timezone'
```

## 参数
<a name="r_AT_TIME_ZONE-arguments"></a>

*timezone*  
返回值的 `TIMEZONE`。该时区可以指定为时区名称（例如 **'Africa/Kampala'** 或者 **'Singapore'**）或作为时区缩写（例如 **'UTC'** 或者 **'PDT'**）。  
要查看支持的时区名称的列表，请执行以下命令。  

```
select pg_timezone_names();
```
 要查看支持的时区缩写的列表，请执行以下命令。  

```
select pg_timezone_abbrevs();
```
 有关更多信息以及示例，请参阅 [时区使用说明](CONVERT_TIMEZONE.md#CONVERT_TIMEZONE-usage-notes)。

## 返回类型
<a name="r_AT_TIME_ZONE-return-type"></a>

与 TIMESTAMP 表达式一起使用时的 TIMESTAMPTZ。与 TIMESTAMPTZ 表达式一起使用时的 TIMESTAMP。

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

以下示例转换不带时区的时间戳值，并将其解释为 MST 时间（POSIX 中的 UTC\$17）。该示例返回 UTC 时区的数据类型为 TIMESTAMPTZ 的值。如果将默认时区配置为 UTC 以外的时区，可能会出现不同的结果。

```
SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'MST';

timezone
------------------------
2001-02-17 03:38:40+00
```

以下示例采用带有时区值的输入时间戳，其中指定时区为 EST（POSIX 中的 UTC\$15），然后将其转换为 MST（POSIX 中的 UTC\$17）。该示例返回一个数据类型为 TIMESTAMP 的值。

```
SELECT TIMESTAMPTZ '2001-02-16 20:38:40-05' AT TIME ZONE 'MST';

timezone
------------------------
2001-02-16 18:38:40
```

# CONVERT\$1TIMEZONE 函数
<a name="CONVERT_TIMEZONE"></a>

CONVERT\$1TIMEZONE 将一个时区的时间戳转换为另一个时区的时间戳。该函数会自动根据夏令时调整。

## 语法
<a name="CONVERT_TIMEZONE-syntax"></a>

```
CONVERT_TIMEZONE( ['source_timezone',] 'target_timezone', 'timestamp')
```

## 参数
<a name="CONVERT_TIMEZONE-arguments"></a>

*source\$1timezone*  
（可选）当前时间戳的时区。默认值为 UTC。有关更多信息，请参阅 [时区使用说明](#CONVERT_TIMEZONE-usage-notes)。

*target\$1timezone*   
新时间戳的时区。有关更多信息，请参阅 [时区使用说明](#CONVERT_TIMEZONE-usage-notes)。

*timestamp*   
时间戳列或隐式转换为时间戳的表达式。

## 返回类型
<a name="CONVERT_TIMEZONE-return-type"></a>

TIMESTAMP

## 时区使用说明
<a name="CONVERT_TIMEZONE-usage-notes"></a>

可指定 *source\$1timezone* 或 *target\$1timezone* 作为时区名称（如“非洲/坎帕拉”或“新加坡”）或作为时区缩写（如“UTC”或“PDT”）。您不必将时区名称转换为其他名称，也不必将缩写转换为其他缩写。例如，您可以从源时区名称“新加坡”中选择一个时间戳，然后将其转换为时区缩写“PDT”中的时间戳。

**注意**  
使用时区名称或时区缩写的结果可能会因当地季节性时间（如夏令时）而有所不同。

### 使用时区名称
<a name="CONVERT_TIMEZONE-using-name"></a>

要查看当前的完整时区名称列表，请运行以下命令。

```
select pg_timezone_names();
```

每行包含一个以逗号分隔的字符串，其中包含时区名称、缩写、UTC 偏移量以及用于指示时区是否遵守夏令时的指示符（`t` 或 `f`）。例如，以下代码段显示了两个生成的行。第一行是时区 `Antarctica/South Pole`、缩写 `NZDT`、UTC 偏移量 `13:00:00`，以及用于指明它不遵守夏令时的 `f`。第二行是时区 `Europe/Paris`、缩写 `CET`、UTC 偏移量 `01:00:00`，以及用于指明它遵守夏令时的 `f`。

```
pg_timezone_names
------------------
(Antarctica/South_Pole,NZDT,13:00:00,t)	
(Europe/Paris,CET,01:00:00,f)
```

运行 SQL 语句以获取整个列表并找到时区名称。返回大约 600 行。虽然部分返回的时区名称是大写的首字母缩略词（例如，GB、PRC、ROK），但 CONVERT\$1TIMEZONE 函数将它们视为时区名称，而不是时区缩写。

如果您使用时区名称指定时区，CONVERT\$1TIMEZONE 会根据夏令时（DST）或在 *timestamp* 指定的日期和时间期间为该时区实行的任何其他当地季节性协议，如夏令时、标准时间或冬令时，自动进行调整。例如，“欧洲/伦敦”在冬季表示 UTC，在夏季加一小时。请注意，Amazon Redshift 使用 [IANA 时区数据库](https://www.iana.org/time-zones)作为时区规范的权威来源。

### 使用时区缩写
<a name="CONVERT_TIMEZONE-using-abbrev"></a>

 要查看当前的完整时区缩写列表，请运行以下命令。

```
select pg_timezone_abbrevs();
```

结果包含一个以逗号分隔的字符串，其中包含时区缩写、UTC 偏移量以及用于指示时区是否遵守夏令时的指示符（`t` 或 `f`）。例如，以下代码段显示了两个生成的行。第一行包含太平洋夏令时的缩写 `PDT`、UTC 偏移量 `-07:00:00`，以及用于指示它遵守夏令时的 `t`。第二行包含太平洋标准时间的缩写 `PST`、UTC 偏移量 `-08:00:00`，以及用于指示它不遵守夏令时的 `f`。

```
pg_timezone_abbrevs
--------------------
(PDT,-07:00:00,t)	
(PST,-08:00:00,f)
```

运行 SQL 语句以获取整个列表，并根据其偏移量和夏令时指示符查找缩写。返回大约 200 行。

时区缩写表示与 UTC 的固定偏移量。如果您使用时区缩写指定时区，CONVERT\$1TIMEZONE 将使用与 UTC 的固定偏移量，并且不会针对任何本地季节性协议进行调整。

### 使用 POSIX 样式格式
<a name="CONVERT_TIMEZONE-using-posix"></a>

POSIX 样式的时区规范采用 *STDoffset* 或 *STDoffsetDST* 的形式，其中 *STD* 是时区缩写，*offset* 是从 UTC 向西的小时数偏移，而 *DST* 是可选的夏令时区缩写。夏令时时间假定为比给定的偏移提前一个小时。

POSIX 样式的时区格式使用格林威治以西的正偏移，而 ISO-8601 约定则使用格林威治以东的正偏移量。

以下是 POSIX 样式时区的示例：
+  PST8
+  PST8PDT
+  EST5
+  EST5EDT

**注意**  
Amazon Redshift 不验证 POSIX 样式时区规格，因此可能将时区设置为无效值。例如，即使将时区设置成了无效值，以下命令也没有返回错误。  

```
set timezone to ‘xxx36’;
```

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

许多示例使用 TICKIT 样本数据集。有关更多信息，请参阅[示例数据库](https://docs.aws.amazon.com/redshift/latest/dg/c_sampledb.html)。

以下示例将时间戳值从默认的 UTC 时区转换为 PST。

```
select convert_timezone('PST', '2008-08-21 07:23:54');
                     
 convert_timezone
------------------------
2008-08-20 23:23:54
```

以下示例将 LISTTIME 列中的时间戳值从默认 UTC 时区转换为 PST。尽管时间戳在夏令时间段内，但它会转换为标准时间，因为目标时区被指定为缩写 (PST)。

```
select listtime, convert_timezone('PST', listtime) from listing
where listid = 16;
                     
     listtime       |   convert_timezone
--------------------+-------------------
2008-08-24 09:36:12     2008-08-24 01:36:12
```

以下示例将 LISTTIME 列中的时间戳从默认 UTC 时区转换为美国/太平洋时区。目标时区使用时区名称，时间戳位于夏令时间段内，因此函数返回夏令时。

```
select listtime, convert_timezone('US/Pacific', listtime) from listing
where listid = 16;
                     
     listtime       |   convert_timezone
--------------------+---------------------
2008-08-24 09:36:12 | 2008-08-24 02:36:12
```

以下示例将时间戳字符串从 EST 转换为 PST：

```
select convert_timezone('EST', 'PST', '20080305 12:25:29');
                     
 convert_timezone
-------------------
2008-03-05 09:25:29
```

以下示例将时间戳转换为美国东部标准时间，因为目标时区使用时区名称 (America/New\$1York)，并且时间戳在标准时间段内。

```
select convert_timezone('America/New_York', '2013-02-01 08:00:00');

 convert_timezone
---------------------
2013-02-01 03:00:00
(1 row)
```

以下示例将时间戳转换为美国东部夏令时，因为目标时区使用时区名称 (America/New\$1York)，并且时间戳在夏令时时间段内。

```
select convert_timezone('America/New_York', '2013-06-01 08:00:00');

 convert_timezone
---------------------
2013-06-01 04:00:00
(1 row)
```

以下示例演示了偏移的用法。

```
SELECT CONVERT_TIMEZONE('GMT','NEWZONE +2','2014-05-17 12:00:00') as newzone_plus_2, 
CONVERT_TIMEZONE('GMT','NEWZONE-2:15','2014-05-17 12:00:00') as newzone_minus_2_15, 
CONVERT_TIMEZONE('GMT','America/Los_Angeles+2','2014-05-17 12:00:00') as la_plus_2,
CONVERT_TIMEZONE('GMT','GMT+2','2014-05-17 12:00:00') as gmt_plus_2;
 
   newzone_plus_2    | newzone_minus_2_15  |      la_plus_2      |     gmt_plus_2
---------------------+---------------------+---------------------+---------------------
2014-05-17 10:00:00 | 2014-05-17 14:15:00 | 2014-05-17 10:00:00 | 2014-05-17 10:00:00
(1 row)
```

# CURRENT\$1DATE 函数
<a name="r_CURRENT_DATE_function"></a>

CURRENT\$1DATE 以默认格式 YYYY-MM-DD 返回当前会话时区（预设情况下为 UTC）中的日期。

**注意**  
CURRENT\$1DATE 返回当前事务的开始日期，而不是当前语句的开始日期。考虑这样的场景，即您在 2008 年 1 月 10 日 23:59 开始一个包含多个语句的事务，而包含 CURRENT\$1DATE 的语句在 2008 年 2 月 10 日 00:00 运行。CURRENT\$1DATE 返回 `10/01/08`，而不是 `10/02/08`。

## 语法
<a name="r_CURRENT_DATE_function-syntax"></a>

```
CURRENT_DATE
```

## 返回类型
<a name="r_CURRENT_DATE_function-return-type"></a>

DATE

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

以下示例返回当前日期（在运行函数的 AWS 区域）。

```
select current_date;

   date
------------
2008-10-01
```

以下示例创建一个表，插入一行，其中列 `todays_date` 的默认设置是 CURRENT\$1DATE，然后选择表中的所有行。

```
CREATE TABLE insert_dates(
    label varchar(128) NOT NULL,
    todays_date DATE DEFAULT CURRENT_DATE);

INSERT INTO insert_dates(label)
VALUES('Date row inserted');

SELECT * FROM insert_dates;
         

 label            | todays_date
------------------+-------------
Date row inserted | 2023-05-10
```

# DATE\$1CMP 函数
<a name="r_DATE_CMP"></a>

DATE\$1CMP 将比较两个日期。如果日期相同，函数将返回 `0`，*date1* 较大时返回 `1`，*date2* 较大时返回 `-1`。

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

```
DATE_CMP(date1, date2)
```

## 参数
<a name="r_DATE_CMP-arguments"></a>

 *date1*   
数据类型 `DATE` 的列，或一个计算结果为 `DATE` 类型的表达式。

 *date2*   
数据类型 `DATE` 的列，或一个计算结果为 `DATE` 类型的表达式。

## 返回类型
<a name="r_DATE_CMP-return-type"></a>

INTEGER

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

以下查询将 CALDATE 列中的 DATE 值与日期 2008 年 1 月 4 日进行比较，并返回 CALDATE 中的值是在 2008 年 1 月 4 日之前（`-1`）、等于这一天（`0`），还是在这一天之后（`1`）：

```
select caldate, '2008-01-04',
date_cmp(caldate,'2008-01-04')
from date
order by dateid
limit 10;

 caldate   |  ?column?  | date_cmp
-----------+------------+----------
2008-01-01 | 2008-01-04 |       -1
2008-01-02 | 2008-01-04 |       -1
2008-01-03 | 2008-01-04 |       -1
2008-01-04 | 2008-01-04 |        0
2008-01-05 | 2008-01-04 |        1
2008-01-06 | 2008-01-04 |        1
2008-01-07 | 2008-01-04 |        1
2008-01-08 | 2008-01-04 |        1
2008-01-09 | 2008-01-04 |        1
2008-01-10 | 2008-01-04 |        1
(10 rows)
```

# DATE\$1CMP\$1TIMESTAMP 函数
<a name="r_DATE_CMP_TIMESTAMP"></a>

DATE\$1CMP\$1TIMESTAMP 将日期与时间戳进行比较，并在值相同时返回 `0`，*date* 按时间顺序较大时返回 `1`，*timestamp* 较大时返回 `-1`。

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

```
DATE_CMP_TIMESTAMP(date, timestamp)
```

## 参数
<a name="r_DATE_CMP_TIMESTAMP-arguments"></a>

 *date*   
数据类型 `DATE` 的列，或一个计算结果为 `DATE` 类型的表达式。

 *timestamp*   
数据类型 `TIMESTAMP` 的列，或一个计算结果为 `TIMESTAMP` 类型的表达式。

## 返回类型
<a name="r_DATE_CMP_TIMESTAMP-return-type"></a>

INTEGER

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

以下示例将日期 `2008-06-18` 与 LISTTIME 进行比较。LISTTIME 列的值是时间戳。在此日期之前创建的清单返回 `1`；此日期之后创建的清单返回 `-1`。

```
select listid, '2008-06-18', listtime,
date_cmp_timestamp('2008-06-18', listtime)
from listing
order by 1, 2, 3, 4
limit 10;

 listid |  ?column?  |      listtime       | date_cmp_timestamp
--------+------------+---------------------+--------------------
      1 | 2008-06-18 | 2008-01-24 06:43:29 |                  1
      2 | 2008-06-18 | 2008-03-05 12:25:29 |                  1
      3 | 2008-06-18 | 2008-11-01 07:35:33 |                 -1
      4 | 2008-06-18 | 2008-05-24 01:18:37 |                  1
      5 | 2008-06-18 | 2008-05-17 02:29:11 |                  1
      6 | 2008-06-18 | 2008-08-15 02:08:13 |                 -1
      7 | 2008-06-18 | 2008-11-15 09:38:15 |                 -1
      8 | 2008-06-18 | 2008-11-09 05:07:30 |                 -1
      9 | 2008-06-18 | 2008-09-09 08:03:36 |                 -1
     10 | 2008-06-18 | 2008-06-17 09:44:54 |                  1
(10 rows)
```

# DATE\$1CMP\$1TIMESTAMPTZ 函数
<a name="r_DATE_CMP_TIMESTAMPTZ"></a>

DATE\$1CMP\$1TIMESTAMPTZ 将日期与带有时区的时间戳进行比较，并在值相同时返回 `0`，*date* 按时间顺序较大时返回 `1`，*timestamptz* 较大时返回 `-1`。

## 语法
<a name="r_DATE_CMP_TIMESTAMPTZ-syntax"></a>

```
DATE_CMP_TIMESTAMPTZ(date, timestamptz)
```

## 参数
<a name="r_DATE_CMP_TIMESTAMPTZ-arguments"></a>

 *date*   
数据类型为 `DATE` 的列，或一个隐式计算结果为 `DATE` 类型的表达式。

 *timestamptz*   
数据类型为 `TIMESTAMPTZ` 的列，或一个隐式计算结果为 `TIMESTAMPTZ` 类型的表达式。

## 返回类型
<a name="r_DATE_CMP_TIMESTAMPTZ-return-type"></a>

INTEGER

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

以下示例将日期 `2008-06-18` 与 LISTTIME 进行比较。在此日期之前创建的清单返回 `1`；此日期之后创建的清单返回 `-1`。

```
select listid, '2008-06-18', CAST(listtime AS timestamptz),
date_cmp_timestamptz('2008-06-18', CAST(listtime AS timestamptz))
from listing
order by 1, 2, 3, 4
limit 10;

 listid |  ?column?  |      timestamptz       | date_cmp_timestamptz
--------+------------+------------------------+----------------------
      1 | 2008-06-18 | 2008-01-24 06:43:29+00 |                  1
      2 | 2008-06-18 | 2008-03-05 12:25:29+00 |                  1
      3 | 2008-06-18 | 2008-11-01 07:35:33+00 |                 -1
      4 | 2008-06-18 | 2008-05-24 01:18:37+00 |                  1
      5 | 2008-06-18 | 2008-05-17 02:29:11+00 |                  1
      6 | 2008-06-18 | 2008-08-15 02:08:13+00 |                 -1
      7 | 2008-06-18 | 2008-11-15 09:38:15+00 |                 -1
      8 | 2008-06-18 | 2008-11-09 05:07:30+00 |                 -1
      9 | 2008-06-18 | 2008-09-09 08:03:36+00 |                 -1
     10 | 2008-06-18 | 2008-06-17 09:44:54+00 |                  1
(10 rows)
```

# DATEADD 函数
<a name="r_DATEADD_function"></a>

按指定的时间间隔递增 DATE、TIME、TIMETZ 或 TIMESTAMP 值。

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

```
DATEADD( datepart, interval, {date|time|timetz|timestamp} )
```

## 参数
<a name="r_DATEADD_function-arguments"></a>

 *datepart*   
函数操作的日期部分（例如年、月、日或小时）。有关更多信息，请参阅 [日期或时间戳函数的日期部分](r_Dateparts_for_datetime_functions.md)。

 *interval*   
指定要添加到目标表达式的时间间隔（例如天数）的整数。负整数减去时间间隔。

 *date*\$1*time*\$1*timetz*\$1*timestamp*  
DATE、TIME、TIMETZ 或 TIMESTAMP 列或隐式转换为 DATE、TIME、TIMETZ 或 TIMESTAMP 的表达式。DATE、TIME、TIMETZ 或 TIMESTAMP 表达式必须包含指定的日期部分。

## 返回类型
<a name="r_DATEADD_function-return-type"></a>

TIMESTAMP 或 TIME 或 TIMETZ，具体取决于输入数据类型。

## 具有 DATE 列的示例
<a name="r_DATEADD_function-examples"></a>

以下示例为 DATE 表中存在的 11 月中的每个日期添加 30 天。

```
select dateadd(day,30,caldate) as novplus30
from date
where month='NOV'
order by dateid;

novplus30
---------------------
2008-12-01 00:00:00
2008-12-02 00:00:00
2008-12-03 00:00:00
...
(30 rows)
```

 以下示例将 18 个月添加到文本日期值。

```
select dateadd(month,18,'2008-02-28');

date_add
---------------------
2009-08-28 00:00:00
(1 row)
```

DATEADD 函数的默认列名称为 DATE\$1ADD。日期值的默认时间戳为 `00:00:00`。

以下示例向未指定时间戳的日期值添加 30 分钟。

```
select dateadd(m,30,'2008-02-28');

date_add
---------------------
2008-02-28 00:30:00
(1 row)
```

您可以用全名或缩写来命名日期部分。在此情况下，*m* 代表几分钟，而不是几个月。

## 具有 TIME 列的示例
<a name="r_DATEADD_function-examples-time"></a>

下面的示例表 TIME\$1TEST 具有一个列 TIME\$1VAL（类型 TIME），其中插入了三个值。

```
select time_val from time_test;
            
time_val
---------------------
20:00:00
00:00:00.5550
00:58:00
```

以下示例为 TIME\$1TEST 表中的每个 TIME\$1VAL 添加 5 分钟。

```
select dateadd(minute,5,time_val) as minplus5 from time_test;
            
minplus5
---------------
20:05:00
00:05:00.5550
01:03:00
```

以下示例为文本时间值添加 8 小时。

```
select dateadd(hour, 8, time '13:24:55');
            
date_add
---------------
21:24:55
```

以下示例显示时间何时超过 24:00:00 或低于 00:00:00。

```
select dateadd(hour, 12, time '13:24:55');
            
date_add
---------------
01:24:55
```

## 具有 TIMETZ 列的示例
<a name="r_DATEADD_function-examples-timetz"></a>

这些示例中的输出值以 UTC 为默认时区。

下面的示例表 TIMETZ\$1TEST 具有一个列 TIMETZ\$1VAL（类型 TIMETZ），其中插入了三个值。

```
select timetz_val from timetz_test;
            
timetz_val
------------------
04:00:00+00
00:00:00.5550+00
05:58:00+00
```

下面的示例为 TIMETZ\$1TEST 表中的每个 TIMETZ\$1VAL 添加 5 分钟。

```
select dateadd(minute,5,timetz_val) as minplus5_tz from timetz_test;
            
minplus5_tz
---------------
04:05:00+00
00:05:00.5550+00
06:03:00+00
```

以下示例将 2 小时添加到一个文本 timetz 值。

```
select dateadd(hour, 2, timetz '13:24:55 PST');
            
date_add
---------------
23:24:55+00
```

## 具有 TIMESTAMP 列的示例
<a name="r_DATEADD_function-examples-timestamp"></a>

这些示例中的输出值以 UTC 为默认时区。

下面的示例表 TIMESTAMP\$1TEST 具有一个列 TIMESTAMP\$1VAL（类型为 TIMESTAMP），其中插入了三个值。

```
SELECT timestamp_val FROM timestamp_test;
            
timestamp_val
------------------
1988-05-15 10:23:31
2021-03-18 17:20:41
2023-06-02 18:11:12
```

以下示例仅向 TIMESTAMP\$1TEST 中 2000 年之前的 TIMESTAMP\$1VAL 值增加 20 年。

```
SELECT dateadd(year,20,timestamp_val) 
FROM timestamp_test
WHERE timestamp_val < to_timestamp('2000-01-01 00:00:00', 'YYYY-MM-DD HH:MI:SS');
            
date_add
---------------
2008-05-15 10:23:31
```

以下示例向不带秒指示器的文本时间戳值增加 5 秒。

```
SELECT dateadd(second, 5, timestamp '2001-06-06');
            
date_add
---------------
2001-06-06 00:00:05
```

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

 DATEADD(month, ...) 和 ADD\$1MONTHS 函数以不同的方式处理位于月末的日期：
+ ADD\$1MONTHS：如果添加到的日期是该月的最后一天，则无论该月有多少天，结果始终是结果月份的最后一天。例如，4 月 30 日 \$1 1 个月是 5 月 31 日。

  ```
  select add_months('2008-04-30',1);
  
  add_months
  ---------------------
  2008-05-31 00:00:00
  (1 row)
  ```
+ DATEADD：如果添加到的日期中的天数少于结果月份，则结果是结果月份的对应日期，而不是该月的最后一天。例如，4 月 30 日 \$1 1 个月是 5 月 30 日。

  ```
  select dateadd(month,1,'2008-04-30');
  
  date_add
  ---------------------
  2008-05-30 00:00:00
  (1 row)
  ```

当使用 dateadd(month, 12,…) 或 dateadd(year, 1, …) 时，DATEADD 函数以不同方式处理闰年日期 02-29。

```
select dateadd(month,12,'2016-02-29');
               
date_add
---------------------
2017-02-28 00:00:00

select dateadd(year, 1, '2016-02-29');

date_add       
---------------------
2017-03-01 00:00:00
```

# DATEDIFF 函数
<a name="r_DATEDIFF_function"></a>

DATEDIFF 返回两个日期或时间表达式的日期部分之间的差异。

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

```
DATEDIFF( datepart, {date|time|timetz|timestamp}, {date|time|timetz|timestamp} )
```

## 参数
<a name="r_DATEDIFF_function-arguments"></a>

 *datepart*   
该函数运行所依据的日期或时间值的特定部分（年、月或日、小时、分钟、秒、毫秒或微秒）。有关更多信息，请参阅 [日期或时间戳函数的日期部分](r_Dateparts_for_datetime_functions.md)。  
具体而言，DATEDIFF 确定在两个表达式之间交叉的日期部分边界的数量。例如，假设您计算两个日期 `12-31-2008` 与 `01-01-2009` 之间的年份差异。在这种情况下，函数返回 1 年，尽管这些日期仅相隔一天。如果您发现两个时间戳 `01-01-2009 8:30:00` 与 `01-01-2009 10:00:00` 之间存在小时差，则结果为 2 小时。如果您发现两个时间戳 `8:30:00` 与 `10:00:00` 之间存在小时差，则结果为 2 小时。

*date*\$1*time*\$1*timetz*\$1*timestamp*  
DATE、TIME、TIMETZ 或 TIMESTAMP 列或隐式转换为 DATE、TIME、TIMETZ 或 TIMESTAMP 的表达式。表达式必须同时包含指定的日期或时间部分。如果第二个日期或时间晚于第一个日期或时间，则结果为正值。如果第二个日期或时间早于第一个日期或时间，则结果为负值。

## 返回类型
<a name="r_DATEDIFF_function-return-type"></a>

BIGINT

## 具有 DATE 列的示例
<a name="r_DATEDIFF_function-examples"></a>

以下示例查找两个文本日期值之间的差异（以周数为单位）。

```
select datediff(week,'2009-01-01','2009-12-31') as numweeks;

numweeks
----------
52
(1 row)
```

以下示例查找两个文本日期值之间的差异，以小时为单位。如果您没有为日期提供时间值，则默认为 00:00:00。

```
select datediff(hour, '2023-01-01', '2023-01-03 05:04:03');
            
date_diff
----------
53
(1 row)
```

以下示例查找两个文本 TIMESTAMETZ 值之间的差异，以天为单位。

```
Select datediff(days, 'Jun 1,2008  09:59:59 EST', 'Jul 4,2008  09:59:59 EST')
         
date_diff
----------
33
```

以下示例查找表中同一行的两个日期之间的差异，以天为单位。

```
select * from date_table;

start_date |   end_date
-----------+-----------
2009-01-01 | 2009-03-23
2023-01-04 | 2024-05-04
(2 rows)

select datediff(day, start_date, end_date) as duration from date_table;
         
duration
---------
      81
     486
(2 rows)
```

以下示例查找过去日期和今天日期中的文本值之间的差异（以季度数为单位）。此示例假定当前日期为 2008 年 6 月 5 日。您可以可以用全名或缩写来命名日期部分。DATEDIFF 函数的默认列名称为 DATE\$1DIFF。

```
select datediff(qtr, '1998-07-01', current_date);

date_diff
-----------
40
(1 row)
```

以下示例将 SALES 和 LISTING 表联接，以计算它们列出后多少天清单 1000 到 1005 的所有票证被售出。这些清单的最长销售等待时间为 15 天，最短等待时间不到一天（0 天）。

```
select priceperticket,
datediff(day, listtime, saletime) as wait
from sales, listing where sales.listid = listing.listid
and sales.listid between 1000 and 1005
order by wait desc, priceperticket desc;

priceperticket | wait
---------------+------
 96.00         |   15
 123.00        |   11
 131.00        |    9
 123.00        |    6
 129.00        |    4
 96.00         |    4
 96.00         |    0
(7 rows)
```

此示例计算卖家等待所有票证销售的平均小时数。

```
select avg(datediff(hours, listtime, saletime)) as avgwait
from sales, listing
where sales.listid = listing.listid;

avgwait
---------
465
(1 row)
```

## 具有 TIME 列的示例
<a name="r_DATEDIFF_function-examples-time"></a>

下面的示例表 TIME\$1TEST 具有一个列 TIME\$1VAL（类型 TIME），其中插入了三个值。

```
select time_val from time_test;
            
time_val
---------------------
20:00:00
00:00:00.5550
00:58:00
```

以下示例查找 TIME\$1VAL 列与时间文本之间的小时数差异。

```
select datediff(hour, time_val, time '15:24:45') from time_test;
         
 date_diff
-----------
        -5
        15
        15
```

以下示例查找两个文本时间值之间的分钟数差异。

```
select datediff(minute, time '20:00:00', time '21:00:00') as nummins;  
         
nummins 
---------- 
60
```

## 具有 TIMETZ 列的示例
<a name="r_DATEDIFF_function-examples-timetz"></a>

下面的示例表 TIMETZ\$1TEST 具有一个列 TIMETZ\$1VAL（类型 TIMETZ），其中插入了三个值。

```
select timetz_val from timetz_test;
            
timetz_val
------------------
04:00:00+00
00:00:00.5550+00
05:58:00+00
```

以下示例查找 TIMETZ 文本与 timetz\$1val 之间的小时数差异。

```
select datediff(hours, timetz '20:00:00 PST', timetz_val) as numhours from timetz_test;

numhours 
---------- 
0
-4
1
```

以下示例查找两个文本 TIMETZ 值之间的小时数差异。

```
select datediff(hours, timetz '20:00:00 PST', timetz '00:58:00 EST') as numhours;
         
numhours 
---------- 
1
```

# DATE\$1PART 函数
<a name="r_DATE_PART_function"></a>

DATE\$1PART 从表达式中提取日期部分值。DATE\$1PART 是 PGDATE\$1PART 函数的同义词。

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

```
DATE_PART(datepart, {date|timestamp})
```

## 参数
<a name="r_DATE_PART_function-arguments"></a>

 *datepart*   
函数所操作的日期值的特定部分（例如年、月或日）的标识符文本或字符串。有关更多信息，请参阅 [日期或时间戳函数的日期部分](r_Dateparts_for_datetime_functions.md)。

\$1*date*\$1*timestamp*\$1  
日期列、时间戳列或隐式转换为日期或时间戳的表达式。*date* 或 *timestamp* 的列或表达式必须包含 *datepart* 中指定的日期部分。

## 返回类型
<a name="r_DATE_PART_function-return-type"></a>

DOUBLE

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

DATE\$1PART 函数的默认列名是 `pgdate_part`。

 有关以下示例中使用的数据的更多信息，请参阅[示例数据库](c_sampledb.md)。

以下示例从时间戳文本中查找分钟。

```
SELECT DATE_PART(minute, timestamp '20230104 04:05:06.789');
            
pgdate_part
-----------
         5
```

以下示例从时间戳文本中查找周编号。周编号计算遵循 ISO 8601 标准。有关更多信息，请参阅 Wikipedia 中的 [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)。

```
SELECT DATE_PART(week, timestamp '20220502 04:05:06.789');
            
pgdate_part
-----------
         18
```

以下示例从时间戳文本中查找月份中的某个日期。

```
SELECT DATE_PART(day, timestamp '20220502 04:05:06.789');
            
pgdate_part
-----------
         2
```

下面的示例从时间戳文本中查找星期几信息。星期几的计算是 0-6 之间的整数，从星期日开始。

```
SELECT DATE_PART(dayofweek, timestamp '20220502 04:05:06.789');
            
pgdate_part
-----------
         1
```

以下示例从时间戳文本中查找世纪。世纪计算遵循 ISO 8601 标准。有关更多信息，请参阅 Wikipedia 中的 [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)。

```
SELECT DATE_PART(century, timestamp '20220502 04:05:06.789');
            
pgdate_part
-----------
         21
```

以下示例从时间戳文本中查找千禧年。千禧年计算遵循 ISO 8601 标准。有关更多信息，请参阅 Wikipedia 中的 [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)。

```
SELECT DATE_PART(millennium, timestamp '20220502 04:05:06.789');
            
pgdate_part
-----------
         3
```

以下示例从时间戳文本中查找微秒。微秒计算遵循 ISO 8601 标准。有关更多信息，请参阅 Wikipedia 中的 [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)。

```
SELECT DATE_PART(microsecond, timestamp '20220502 04:05:06.789');
            
pgdate_part
-----------
    789000
```

以下示例从日期文本中查找月份。

```
SELECT DATE_PART(month, date '20220502');
            
pgdate_part
-----------
         5
```

以下示例将 DATE\$1PART 函数应用于表中的列。

```
SELECT date_part(w, listtime) AS weeks, listtime
FROM listing 
WHERE listid=10
            

weeks |      listtime
------+---------------------
 25   | 2008-06-17 09:44:54
(1 row)
```

您可以用全名或缩写来命名日期部分；在这种情况下，*w* 代表星期数。

星期日期部分返回一个从 0-6 整数，从星期日开始。将 DATE\$1PART 与 dow (DAYOFWEEK) 结合使用以查看星期六的活动。

```
SELECT date_part(dow, starttime) AS dow, starttime 
FROM event
WHERE date_part(dow, starttime)=6
ORDER BY 2,1;     

 dow |      starttime
-----+---------------------
   6 | 2008-01-05 14:00:00
   6 | 2008-01-05 14:00:00
   6 | 2008-01-05 14:00:00
   6 | 2008-01-05 14:00:00
...
(1147 rows)
```

# DATE\$1PART\$1YEAR 函数
<a name="r_DATE_PART_YEAR"></a>

DATE\$1PART\$1YEAR 函数从日期中提取年份。

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

```
DATE_PART_YEAR(date)
```

## 参数
<a name="r_DATE_PART_YEAR-argument"></a>

 *date*   
数据类型为 `DATE` 的列，或一个隐式计算结果为 `DATE` 类型的表达式。

## 返回类型
<a name="r_DATE_PART_YEAR-return-type"></a>

INTEGER

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

以下示例从日期文本中查找年份。

```
SELECT DATE_PART_YEAR(date '20220502 04:05:06.789');

date_part_year
---------------
2022
```

以下示例从 CALDATE 列中提取年份。CALDATE 列中的值是日期。有关此示例中使用的数据的更多信息，请参阅[示例数据库](c_sampledb.md)。

```
select caldate, date_part_year(caldate)
from date
order by
dateid limit 10;

 caldate   | date_part_year
-----------+----------------
2008-01-01 |           2008
2008-01-02 |           2008
2008-01-03 |           2008
2008-01-04 |           2008
2008-01-05 |           2008
2008-01-06 |           2008
2008-01-07 |           2008
2008-01-08 |           2008
2008-01-09 |           2008
2008-01-10 |           2008
(10 rows)
```

# DATE\$1TRUNC 函数
<a name="r_DATE_TRUNC"></a>

DATE\$1TRUNC 函数根据您指定的日期部分（如小时、天或月）截断时间戳表达式或文字。

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

```
DATE_TRUNC('datepart', timestamp)
```

## 参数
<a name="r_DATE_TRUNC-arguments"></a>

 *datepart*   
截断时间戳值的日期部分。输入*时间戳*被截断为输入 *datepart* 的精度。例如，`month` 截断至每月的第一天。有效格式如下所示：  
+ microsecond、microseconds
+ millisecond、milliseconds
+ second、seconds
+ minute、minutes
+ hour、hours
+ day、days
+ week、weeks
+ month、months
+ quarter、quarters
+ year、years
+ decade、decades
+ century、centuries
+ millennium、millennia
有关某些格式的缩写的更多信息，请参阅[日期或时间戳函数的日期部分](r_Dateparts_for_datetime_functions.md)

 *timestamp*   
时间戳列或隐式转换为时间戳的表达式。

## 返回类型
<a name="r_DATE_TRUNC-return-type"></a>

TIMESTAMP

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

将输入时间戳截断至秒。

```
SELECT DATE_TRUNC('second', TIMESTAMP '20200430 04:05:06.789');
date_trunc
2020-04-30 04:05:06
```

将输入时间戳截断至分钟。

```
SELECT DATE_TRUNC('minute', TIMESTAMP '20200430 04:05:06.789');
date_trunc
2020-04-30 04:05:00
```

将输入时间戳截断至小时。

```
SELECT DATE_TRUNC('hour', TIMESTAMP '20200430 04:05:06.789');
date_trunc
2020-04-30 04:00:00
```

将输入时间戳截断至天。

```
SELECT DATE_TRUNC('day', TIMESTAMP '20200430 04:05:06.789');
date_trunc
2020-04-30 00:00:00
```

将输入时间戳截断至一个月的第一天。

```
SELECT DATE_TRUNC('month', TIMESTAMP '20200430 04:05:06.789');
date_trunc
2020-04-01 00:00:00
```

将输入时间戳截断至一个季度的第一天。

```
SELECT DATE_TRUNC('quarter', TIMESTAMP '20200430 04:05:06.789');
date_trunc
2020-04-01 00:00:00
```

将输入时间戳截断至一年的第一天。

```
SELECT DATE_TRUNC('year', TIMESTAMP '20200430 04:05:06.789');
date_trunc
2020-01-01 00:00:00
```

将输入时间戳截断至一个世纪的第一天。

```
SELECT DATE_TRUNC('millennium', TIMESTAMP '20200430 04:05:06.789');
date_trunc
2001-01-01 00:00:00
```

将输入时间戳截断至某周的星期一。

```
select date_trunc('week', TIMESTAMP '20220430 04:05:06.789');
date_trunc
2022-04-25 00:00:00
```

在以下示例中，DATE\$1TRUNC 函数使用“周”日期部分返回每周星期一的日期。

```
select date_trunc('week', saletime), sum(pricepaid) from sales where
saletime like '2008-09%' group by date_trunc('week', saletime) order by 1;

date_trunc  |    sum
------------+-------------
2008-09-01  | 2474899
2008-09-08  | 2412354
2008-09-15  | 2364707
2008-09-22  | 2359351
2008-09-29  |  705249
```

# EXTRACT 函数
<a name="r_EXTRACT_function"></a>

EXTRACT 函数返回 TIMESTAMP、TIMESTAMPTZ、TIME、TIMETZ、INTERVAL YEAR TO MONTH 或 INTERVAL DAY TO SECOND 值中的日期或时间部分。示例包括时间戳中的日、月、年、小时、分钟、秒、毫秒或微秒。

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

```
EXTRACT(datepart FROM source)
```

## 参数
<a name="r_EXTRACT_function-arguments"></a>

 *datepart*   
要提取的日期或时间的子字段，例如日、月、年、小时、分钟、毫秒或微秒。有关可能的值，请参阅[日期或时间戳函数的日期部分](r_Dateparts_for_datetime_functions.md)。

 *source*   
计算结果为 TIMESTAMP、TIMESTAMPTZ、TIME、TIMETZ、INTERVAL YEAR TO MONTH 或 INTERVAL DAY TO SECOND 数据类型的列或表达式。

## 返回类型
<a name="r_EXTRACT_function-return-type"></a>

如果 *source* 值的计算结果为数据类型 TIMESTAMP、TIME、TIMETZ、INTERVAL YEAR TO MONTH 或 INTERVAL DAY TO SECOND，则为 INTEGER。

如果 *source* 值的计算结果为数据类型 TIMESTAMPTZ，则为 DOUBLE PRECISION。

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

以下示例确定支付价格为 10000 美元或更高的销售周数。此示例使用 TICKIT 数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

```
select salesid, extract(week from saletime) as weeknum
from sales 
where pricepaid > 9999 
order by 2;

salesid | weeknum
--------+---------
 159073 |       6
 160318 |       8
 161723 |      26
```

以下示例从文本时间戳值返回分钟值。

```
select extract(minute from timestamp '2009-09-09 12:08:43');
            
date_part
-----------
8
```

以下示例从文本时间戳值返回毫秒值。

```
select extract(ms from timestamp '2009-09-09 12:08:43.101');
            
date_part
-----------
101
```

## TIMESTAMPZ 示例
<a name="r_EXTRACT_function-examples-timestamptz"></a>

以下示例从文本 timestamptz 值返回年份值。

```
select extract(year from timestamptz '1.12.1997 07:37:16.00 PST');
            
date_part
-----------
1997
```

## TIME 示例
<a name="r_EXTRACT_function-examples-time"></a>

下面的示例表 TIME\$1TEST 具有一个列 TIME\$1VAL（类型 TIME），其中插入了三个值。

```
select time_val from time_test;
            
time_val
---------------------
20:00:00
00:00:00.5550
00:58:00
```

以下示例从每个 time\$1val 中提取分钟数。

```
select extract(minute from time_val) as minutes from time_test;
            
minutes
-----------
         0
         0
         58
```

以下示例从每个 time\$1val 中提取小时数。

```
select extract(hour from time_val) as hours from time_test;
            
hours
-----------
         20
         0
         0
```

以下示例从文本值中提取毫秒。

```
select extract(ms from time '18:25:33.123456');
            
 date_part
-----------
     123
```

## TIMETZ 示例
<a name="r_EXTRACT_function-examples-timetz"></a>

下面的示例表 TIMETZ\$1TEST 具有一个列 TIMETZ\$1VAL（类型 TIMETZ），其中插入了三个值。

```
select timetz_val from timetz_test;
            
timetz_val
------------------
04:00:00+00
00:00:00.5550+00
05:58:00+00
```

以下示例从每个 timetz\$1val 中提取小时数。

```
select extract(hour from timetz_val) as hours from time_test;
            
hours
-----------
         4
         0
         5
```

以下示例从文本值中提取毫秒。在处理提取之前，文本不会转换为 UTC。

```
select extract(ms from timetz '18:25:33.123456 EST');
            
 date_part
-----------
     123
```

以下示例从文本 timetz 值返回与 UTC 的时区偏移小时数。

```
select extract(timezone_hour from timetz '1.12.1997 07:37:16.00 PDT');
            
date_part
-----------
-7
```

## INTERVAL YEAR TO MONTH 和 INTERVAL DAY TO SECOND 示例
<a name="r_EXTRACT_function-examples-interval"></a>

以下示例从定义 36 小时（即 1 天 12 小时）的 INTERVAL DAY TO SECOND 中提取 `1` 的日部分。

```
select EXTRACT('days' from INTERVAL '36 hours' DAY TO SECOND)
  
 date_part
------------------
 1
```

以下示例从定义 15 个月（即 1 年 3 个月）的 YEAR TO MONTH 中提取 `3` 的月份部分。

```
select EXTRACT('month' from INTERVAL '15 months' YEAR TO MONTH)
  
 date_part
------------------
 3
```

以下示例从 30 个月（即 2 年 6 个月）中提取 `6` 的月份部分。

```
select EXTRACT('month' from INTERVAL '30' MONTH)
   
 date_part
------------------
 6
```

以下示例从 50 个小时（即 2 天 2 小时）中提取 `2` 的小时部分。

```
select EXTRACT('hours' from INTERVAL '50' HOUR)
  
 date_part
------------------
 2
```

以下示例从 1 小时 11 分 11.123 秒中提取 `11` 的分钟部分。

```
select EXTRACT('minute' from INTERVAL '70 minutes 70.123 seconds' MINUTE TO SECOND)
  
 date_part
------------------
 11
```

以下示例从 1 天 1 小时 1 分 1.11 秒中提取 `1.11` 的秒部分。

```
select EXTRACT('seconds' from INTERVAL '1 day 1:1:1.11' DAY TO SECOND)
  
 date_part
------------------
 1.11
```

以下示例提取 INTERVAL 中的总小时数。提取每个部分并将其添加到总数中。

```
select EXTRACT('days' from INTERVAL '50' HOUR) * 24 + EXTRACT('hours' from INTERVAL '50' HOUR)
 
 ?column?
------------------
 50
```

以下示例提取 INTERVAL 中的总秒数。提取每个部分并将其添加到总数中。

```
select EXTRACT('days' from INTERVAL '1 day 1:1:1.11' DAY TO SECOND) * 86400 + 
       EXTRACT('hours' from INTERVAL '1 day 1:1:1.11' DAY TO SECOND) * 3600 +
       EXTRACT('minutes' from INTERVAL '1 day 1:1:1.11' DAY TO SECOND) * 60 + 
       EXTRACT('seconds' from INTERVAL '1 day 1:1:1.11' DAY TO SECOND)
  
 ?column?
------------------
 90061.11
```

# GETDATE 函数
<a name="r_GETDATE"></a>

GETDATE 返回当前会话时区（预设情况下为 UTC）中的当前日期和时间。它返回当前语句的开始日期或时间，即使它在事务块中也是如此。

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

```
GETDATE()
```

括号为必填项。

## 返回类型
<a name="r_GETDATE-return-type"></a>

TIMESTAMP

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

以下示例使用 GETDATE 函数返回当前日期的完整时间戳。

```
select getdate();

timestamp
---------------------
2008-12-04 16:10:43
```

以下示例使用 TRUNC 函数内的 GETDATE 函数来返回没有时间的当前日期。

```
select trunc(getdate());

trunc
------------
2008-12-04
```

# INTERVAL\$1CMP 函数
<a name="r_INTERVAL_CMP"></a>

INTERVAL\$1CMP 比较两个时间间隔并在第一个时间间隔较大时返回 `1`，在第二个时间间隔较大时返回 `-1`，并在时间间隔相等时返回 `0`。有关更多信息，请参阅 [不带限定词语法的间隔文字示例](r_interval_literals.md)。

## 语法
<a name="r_INTERVAL_CMP-syntax"></a>

```
INTERVAL_CMP(interval1, interval2)
```

## 参数
<a name="r_INTERVAL_CMP-arguments"></a>

 *interval1*   
时间间隔文本值。

 *interval2*   
时间间隔文本值。

## 返回类型
<a name="r_INTERVAL_CMP-return-type"></a>

INTEGER

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

以下示例将 `3 days` 的值与 `1 year` 进行比较。

```
select interval_cmp('3 days','1 year');

interval_cmp
--------------
-1
```

此示例比较了值 `7 days` 与 `1 week`。

```
select interval_cmp('7 days','1 week');

interval_cmp
--------------
0
```

以下示例将 `1 year` 的值与 `3 days` 进行比较。

```
select interval_cmp('1 year','3 days');

interval_cmp
--------------
1
```

# LAST\$1DAY 函数
<a name="r_LAST_DAY"></a>

LAST\$1DAY 返回该月最后一天的日期，该日期包含 *date*。无论 *date* 参数的数据类型如何，返回类型始终为 DATE。

有关检索特定日期部分的更多信息，请参阅[DATE\$1TRUNC 函数](r_DATE_TRUNC.md)。

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

```
LAST_DAY( { date | timestamp } )
```

## 参数
<a name="r_LAST_DAY-arguments"></a>

*date* \$1 *timestamp*

数据类型为 `DATE` 或 `TIMESTAMP` 的列，或一个隐式计算结果为 `DATE` 或 `TIMESTAMP` 类型的表达式。

## 返回类型
<a name="r_LAST_DAY-return-type"></a>

DATE

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

以下示例返回当前月份最后一天的日期。

```
select last_day(sysdate);

  last_day
------------
 2014-01-31
```

以下示例返回该月最后 7 天每天售出的票证数量。SALETIME 列中的值是时间戳。

```
select datediff(day, saletime, last_day(saletime)) as "Days Remaining", sum(qtysold)
from sales
where datediff(day, saletime, last_day(saletime)) < 7
group by 1
order by 1;

days remaining |  sum
---------------+-------
             0 | 10140
             1 | 11187
             2 | 11515
             3 | 11217
             4 | 11446
             5 | 11708
             6 | 10988
(7 rows)
```

# MONTHS\$1BETWEEN 函数
<a name="r_MONTHS_BETWEEN_function"></a>

MONTHS\$1BETWEEN 确定两个日期之间相隔的月数。

如果第一个日期晚于第二个日期，则结果为正；否则，结果为负数。

如果任一参数为 null，则结果为 NULL。

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

```
MONTHS_BETWEEN( date1, date2 )
```

## 参数
<a name="r_MONTHS_BETWEEN_function-arguments"></a>

 *date1*   
数据类型为 `DATE` 的列，或一个隐式计算结果为 `DATE` 类型的表达式。

 *date2*   
数据类型为 `DATE` 的列，或一个隐式计算结果为 `DATE` 类型的表达式。

## 返回类型
<a name="r_MONTHS_BETWEEN_function-return-type"></a>

FLOAT8

结果的整数部分基于日期的年份和月份值之间的差值。结果的小数部分根据日期的日期和时间戳值计算，假定一个月为 31 天。

如果 *date1* 和 *date2* 都包含一个月内的相同日期（例如，1/15/14 和 2/15/14）或该月的最后一天（例如 8/31/14 和 9/30/14），则结果是基于日期的年份和月份值的整数，无论时间戳部分是否匹配（如果存在）。

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

以下示例返回 1969 年 1 月 18 日至 1969 年 3 月 18 日之间的月份。

```
select months_between('1969-01-18', '1969-03-18')
as months;

months
----------
-2
```

以下示例返回 1969 年 1 月 18 日至 1969 年 1 月 18 日之间的月数。

```
select months_between('1969-01-18', '1969-01-18')
as months;

months
----------
0
```

 以下示例返回事件的第一个和最后一个展示之间的月份。

```
select eventname, 
min(starttime) as first_show,
max(starttime) as last_show,
months_between(max(starttime),min(starttime)) as month_diff
from event 
group by eventname
order by eventname
limit 5;

eventname         first_show             last_show              month_diff
---------------------------------------------------------------------------
.38 Special       2008-01-21 19:30:00.0  2008-12-25 15:00:00.0  11.12
3 Doors Down      2008-01-03 15:00:00.0  2008-12-01 19:30:00.0  10.94
70s Soul Jam      2008-01-16 19:30:00.0  2008-12-07 14:00:00.0  10.7
A Bronx Tale      2008-01-21 19:00:00.0  2008-12-15 15:00:00.0  10.8
A Catered Affair  2008-01-08 19:30:00.0  2008-12-19 19:00:00.0  11.35
```

# NEXT\$1DAY 函数
<a name="r_NEXT_DAY"></a>

NEXT\$1DAY 返回比给定日期晚的指定日期的第一个实例的日期。

如果 *day* 值与给定日期为一个星期中的同一天，则会返回当天的下一个匹配项。

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

```
NEXT_DAY( { date | timestamp }, day )
```

## 参数
<a name="r_NEXT_DAY-arguments"></a>

 *date* \$1 *timestamp*  
数据类型为 `DATE` 或 `TIMESTAMP` 的列，或一个隐式计算结果为 `DATE` 或 `TIMESTAMP` 类型的表达式。

 *day*   
一个包含任何日期的名称的字符串。大小写不重要。  
有效的值如下所示。      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_NEXT_DAY.html)

## 返回类型
<a name="r_NEXT_DAY-return-type"></a>

DATE

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

以下示例返回 2014 年 8 月 20 日之后第一个星期二的日期。

```
select next_day('2014-08-20','Tuesday');

next_day
-----------
2014-08-26
```

以下示例返回 2008 年 1 月 1 日之后的第一个星期二的日期，时间为 5:54:44。

```
select listtime, next_day(listtime, 'Tue') from listing limit 1;

listtime            | next_day
--------------------+-----------
2008-01-01 05:54:44 | 2008-01-08
```

以下示例获取第三季度的目标营销日期。

```
select username, (firstname ||' '|| lastname) as name,
eventname, caldate, next_day (caldate, 'Monday') as marketing_target
from sales, date, users, event
where sales.buyerid = users.userid
and sales.eventid = event.eventid
and event.dateid = date.dateid
and date.qtr = 3
order by marketing_target, eventname, name;

username  |     name          |     eventname        |    caldate   |   marketing_target
----------+-------------------+----------------------+--------------+-------------------
MBO26QSG  |   Callum Atkinson | .38 Special          |  2008-07-06  |	2008-07-07
WCR50YIU  |   Erasmus Alvarez | A Doll's House       |  2008-07-03  |	2008-07-07
CKT70OIE  |   Hadassah Adkins | Ana Gabriel          |  2008-07-06  |	2008-07-07
VVG07OUO  |   Nathan Abbott   | Armando Manzanero    |  2008-07-04  |	2008-07-07
GEW77SII  |   Scarlet Avila   | August: Osage County |  2008-07-06  |	2008-07-07
ECR71CVS  |   Caryn Adkins    | Ben Folds            |  2008-07-03  |	2008-07-07
KUW82CYU  |   Kaden Aguilar   | Bette Midler         |  2008-07-01  |	2008-07-07
WZE78DJZ  |   Kay Avila       | Bette Midler         |  2008-07-01  |	2008-07-07
HXY04NVE  |   Dante Austin    | Britney Spears       |  2008-07-02  |	2008-07-07
URY81YWF  |   Wilma Anthony   | Britney Spears       |  2008-07-02  |	2008-07-07
```

# SYSDATE 函数
<a name="r_SYSDATE"></a>

SYSDATE 返回当前会话时区（预设情况下为 UTC）中的当前日期和时间。

**注意**  
SYSDATE 返回当前事务的开始日期和时间，而不是当前语句的开始日期和时间。

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

```
SYSDATE
```

此函数不需要任何参数。

## 返回类型
<a name="r_SYSDATE-return-type"></a>

TIMESTAMP

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

以下示例使用 SYSDATE 函数返回当前日期的完整时间戳。

```
select sysdate;

timestamp
----------------------------
2008-12-04 16:10:43.976353
```

以下示例使用 TRUNC 函数内的 SYSDATE 函数来返回没有时间的当前日期。

```
select trunc(sysdate);

trunc
------------
2008-12-04
```

以下查询返回介于发出查询的日期和 120 天之前的任何日期之间的日期的销售信息。

```
select salesid, pricepaid, trunc(saletime) as saletime, trunc(sysdate) as now
from sales
where saletime between trunc(sysdate)-120 and trunc(sysdate)
order by saletime asc;

 salesid | pricepaid |  saletime  |    now
---------+-----------+------------+------------
91535    |    670.00 | 2008-08-07 | 2008-12-05
91635    |    365.00 | 2008-08-07 | 2008-12-05
91901    |   1002.00 | 2008-08-07 | 2008-12-05
...
```

# TIMEOFDAY 函数
<a name="r_TIMEOFDAY_function"></a>

TIMEOFDAY 是一个特殊的别名，用于将工作日、日期和时间作为字符串值返回。它返回当前语句的时间字符串，即使它在事务块内也是如此。

## 语法
<a name="r_TIMEOFDAY_function-syntax"></a>

```
TIMEOFDAY()
```

## 返回类型
<a name="r_TIMEOFDAY_function-return-type"></a>

VARCHAR

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

以下示例通过使用 TIMEOFDAY 函数返回当前日期和时间。

```
select timeofday();

timeofday
------------
Thu Sep 19 22:53:50.333525 2013 UTC
```

# TIMESTAMP\$1CMP 函数
<a name="r_TIMESTAMP_CMP"></a>

比较两个字符串的值并返回整数。如果时间戳相同，此函数返回 `0`。如果第一个时间戳较大，则函数返回 `1`。如果第二个时间戳较大，则函数返回 `-1`。

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

```
TIMESTAMP_CMP(timestamp1, timestamp2)
```

## 参数
<a name="r_TIMESTAMP_CMP-arguments"></a>

 *timestamp1*   
数据类型为 `TIMESTAMP` 的列，或一个隐式计算结果为 `TIMESTAMP` 类型的表达式。

 *timestamp2*   
数据类型为 `TIMESTAMP` 的列，或一个隐式计算结果为 `TIMESTAMP` 类型的表达式。

## 返回类型
<a name="r_TIMESTAMP_CMP-return-type"></a>

INTEGER

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

以下示例比较了时间戳并显示了比较结果。

```
SELECT TIMESTAMP_CMP('2008-01-24 06:43:29', '2008-01-24 06:43:29'), TIMESTAMP_CMP('2008-01-24 06:43:29', '2008-02-18 02:36:48'), TIMESTAMP_CMP('2008-02-18 02:36:48', '2008-01-24 06:43:29');

timestamp_cmp  | timestamp_cmp | timestamp_cmp 
---------------+---------------+---------------
             0 |            -1 |             1
```

以下示例比较清单的 LISTTIME 和 SALETIME。对于所有上架项，TIMESTAMP\$1CMP 的值都是 `-1`，因为销售的时间戳都在上架时间戳之后。

```
select listing.listid, listing.listtime,
sales.saletime, timestamp_cmp(listing.listtime, sales.saletime)
from listing, sales
where listing.listid=sales.listid
order by 1, 2, 3, 4
limit 10;

 listid |      listtime       |      saletime       | timestamp_cmp
--------+---------------------+---------------------+---------------
      1 | 2008-01-24 06:43:29 | 2008-02-18 02:36:48 |            -1
      4 | 2008-05-24 01:18:37 | 2008-06-06 05:00:16 |            -1
      5 | 2008-05-17 02:29:11 | 2008-06-06 08:26:17 |            -1
      5 | 2008-05-17 02:29:11 | 2008-06-09 08:38:52 |            -1
      6 | 2008-08-15 02:08:13 | 2008-08-31 09:17:02 |            -1
     10 | 2008-06-17 09:44:54 | 2008-06-26 12:56:06 |            -1
     10 | 2008-06-17 09:44:54 | 2008-07-10 02:12:36 |            -1
     10 | 2008-06-17 09:44:54 | 2008-07-16 11:59:24 |            -1
     10 | 2008-06-17 09:44:54 | 2008-07-22 02:23:17 |            -1
     12 | 2008-07-25 01:45:49 | 2008-08-04 03:06:36 |            -1
(10 rows)
```

此示例显示 TIMESTAMP\$1CMP 对于相同的时间戳返回 0：

```
select listid, timestamp_cmp(listtime, listtime)
from listing
order by 1 , 2
limit 10;

 listid | timestamp_cmp
--------+---------------
      1 |             0
      2 |             0
      3 |             0
      4 |             0
      5 |             0
      6 |             0
      7 |             0
      8 |             0
      9 |             0
     10 |             0
(10 rows)
```

# TIMESTAMP\$1CMP\$1DATE 函数
<a name="r_TIMESTAMP_CMP_DATE"></a>

TIMESTAMP\$1CMP\$1DATE 将时间戳和日期的值进行比较。如果时间戳和日期值相同，则此函数返回 `0`。如果时间戳按时间顺序较大，则函数返回 `1`。如果日期较大，则函数返回 `-1`。

## 语法
<a name="r_TIMESTAMP_CMP_DATE-syntax"></a>

```
TIMESTAMP_CMP_DATE(timestamp, date)
```

## 参数
<a name="r_TIMESTAMP_CMP_DATE-arguments"></a>

 *timestamp*   
数据类型为 `TIMESTAMP` 的列，或一个隐式计算结果为 `TIMESTAMP` 类型的表达式。

 *:date*   
数据类型为 `DATE` 的列，或一个隐式计算结果为 `DATE` 类型的表达式。

## 返回类型
<a name="r_TIMESTAMP_CMP_DATE-return-type"></a>

INTEGER

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

以下示例将 LISTTIME 与日期 `2008-06-18` 进行比较。在此日期之后创建的清单返回 `1`；此日期之前创建的清单返回 `-1`。LISTTIME 值是时间戳。

```
select listid, listtime,
timestamp_cmp_date(listtime, '2008-06-18')
from listing
order by 1, 2, 3
limit 10;


 listid |      listtime       | timestamp_cmp_date
--------+---------------------+--------------------
      1 | 2008-01-24 06:43:29 |              -1
      2 | 2008-03-05 12:25:29 |              -1
      3 | 2008-11-01 07:35:33 |               1
      4 | 2008-05-24 01:18:37 |              -1
      5 | 2008-05-17 02:29:11 |              -1
      6 | 2008-08-15 02:08:13 |               1
      7 | 2008-11-15 09:38:15 |               1
      8 | 2008-11-09 05:07:30 |               1
      9 | 2008-09-09 08:03:36 |               1
     10 | 2008-06-17 09:44:54 |              -1
(10 rows)
```

# TIMESTAMP\$1CMP\$1TIMESTAMPTZ 函数
<a name="r_TIMESTAMP_CMP_TIMESTAMPTZ"></a>

TIMESTAMP\$1CMP\$1TIMESTAMPTZ 将时间戳表达式的值与带有时区的时间戳表达式进行比较。如果时间戳与带有时区的时间戳值相同，则函数返回 `0`。如果时间戳按时间顺序较大，则函数返回 `1`。如果具有时区的时间戳较大，则函数返回 `–1`。

## 语法
<a name="r_TIMESTAMP_CMP_TIMESTAMPTZ-syntax"></a>

```
TIMESTAMP_CMP_TIMESTAMPTZ(timestamp, timestamptz)
```

## 参数
<a name="r_TIMESTAMP_CMP_TIMESTAMPTZ-arguments"></a>

 *timestamp*   
数据类型为 `TIMESTAMP` 的列，或一个隐式计算结果为 `TIMESTAMP` 类型的表达式。

 *timestamptz*   
数据类型为 `TIMESTAMPTZ` 的列，或一个隐式计算结果为 `TIMESTAMPTZ` 类型的表达式。

## 返回类型
<a name="r_TIMESTAMP_CMP_TIMESTAMPTZ-return-type"></a>

INTEGER

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

以下示例将时间戳与带有时区的时间戳进行比较，并显示比较结果。

```
SELECT TIMESTAMP_CMP_TIMESTAMPTZ('2008-01-24 06:43:29', '2008-01-24 06:43:29+00'), TIMESTAMP_CMP_TIMESTAMPTZ('2008-01-24 06:43:29', '2008-02-18 02:36:48+00'), TIMESTAMP_CMP_TIMESTAMPTZ('2008-02-18 02:36:48', '2008-01-24 06:43:29+00');

timestamp_cmp_timestamptz  | timestamp_cmp_timestamptz | timestamp_cmp_timestamptz 
---------------------------+---------------------------+--------------------------
             0             |            -1             |             1
```

# TIMESTAMPTZ\$1CMP 函数
<a name="r_TIMESTAMPTZ_CMP"></a>

TIMESTAMPTZ\$1CMP 比较两个时间戳的值与时区值并返回整数。如果时间戳相同，此函数返回 `0`。如果第一个时间戳按时间顺序较大，则函数返回 `1`。如果第二个时间戳较大，则函数返回 `–1`。

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

```
TIMESTAMPTZ_CMP(timestamptz1, timestamptz2)
```

## 参数
<a name="r_TIMESTAMPTZ_CMP-arguments"></a>

 *timestamptz1*   
数据类型为 `TIMESTAMPTZ` 的列，或一个隐式计算结果为 `TIMESTAMPTZ` 类型的表达式。

 *timestamptz2*   
数据类型为 `TIMESTAMPTZ` 的列，或一个隐式计算结果为 `TIMESTAMPTZ` 类型的表达式。

## 返回类型
<a name="r_TIMESTAMPTZ_CMP-return-type"></a>

INTEGER

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

以下示例比较了带有时区的时间戳，并显示比较的结果。

```
SELECT TIMESTAMPTZ_CMP('2008-01-24 06:43:29+00', '2008-01-24 06:43:29+00'), TIMESTAMPTZ_CMP('2008-01-24 06:43:29+00', '2008-02-18 02:36:48+00'), TIMESTAMPTZ_CMP('2008-02-18 02:36:48+00', '2008-01-24 06:43:29+00');

timestamptz_cmp  | timestamptz_cmp | timestamptz_cmp
-----------------+-----------------+----------------
        0        |       -1        |       1
```

# TIMESTAMPTZ\$1CMP\$1DATE 函数
<a name="r_TIMESTAMPTZ_CMP_DATE"></a>

TIMESTAMPTZ\$1CMP\$1DATE 将时间戳和日期的值进行比较。如果时间戳和日期值相同，则此函数返回 `0`。如果时间戳按时间顺序较大，则函数返回 `1`。如果日期较大，则函数返回 `–1`。

## 语法
<a name="r_TIMESTAMPTZ_CMP_DATE-syntax"></a>

```
TIMESTAMPTZ_CMP_DATE(timestamptz, date)
```

## 参数
<a name="r_TIMESTAMPTZ_CMP_DATE-arguments"></a>

 *timestamptz*   
数据类型为 `TIMESTAMPTZ` 的列，或一个隐式计算结果为 `TIMESTAMPTZ` 类型的表达式。

 *:date*   
数据类型为 `DATE` 的列，或一个隐式计算结果为 `DATE` 类型的表达式。

## 返回类型
<a name="r_TIMESTAMPTZ_CMP_DATE-return-type"></a>

INTEGER

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

以下示例将 LISTTIME 作为带有时区的时间戳与日期 `2008-06-18` 进行比较。在此日期之后创建的清单返回 `1`；此日期之前创建的清单返回 `-1`。

```
select listid, CAST(listtime as timestamptz) as tstz,
timestamp_cmp_date(tstz, '2008-06-18')
from listing
order by 1, 2, 3
limit 10;


 listid |          tstz          | timestamptz_cmp_date
--------+------------------------+----------------------
      1 | 2008-01-24 06:43:29+00 |              -1
      2 | 2008-03-05 12:25:29+00 |              -1
      3 | 2008-11-01 07:35:33+00 |               1
      4 | 2008-05-24 01:18:37+00 |              -1
      5 | 2008-05-17 02:29:11+00 |              -1
      6 | 2008-08-15 02:08:13+00 |               1
      7 | 2008-11-15 09:38:15+00 |               1
      8 | 2008-11-09 05:07:30+00 |               1
      9 | 2008-09-09 08:03:36+00 |               1
     10 | 2008-06-17 09:44:54+00 |              -1
(10 rows)
```

# TIMESTAMPTZ\$1CMP\$1TIMESTAMP 函数
<a name="r_TIMESTAMPTZ_CMP_TIMESTAMP"></a>

TIMESTAMPTZ\$1CMP\$1TIMESTAMP 将带有时区的时间戳表达式的值与时间戳表达式进行比较。如果带有时区的时间戳与时间戳值相同，则函数返回 `0`。如果带有时区的时间戳按时间顺序较大，则函数返回 `1`。如果时间戳较大，则函数返回 `–1`。

## 语法
<a name="r_TIMESTAMPTZ_CMP_TIMESTAMP-syntax"></a>

```
TIMESTAMPTZ_CMP_TIMESTAMP(timestamptz, timestamp)
```

## 参数
<a name="r_TIMESTAMPTZ_CMP_TIMESTAMP-arguments"></a>

 *timestamptz*   
数据类型为 `TIMESTAMPTZ` 的列，或一个隐式计算结果为 `TIMESTAMPTZ` 类型的表达式。

 *timestamp*   
数据类型为 `TIMESTAMP` 的列，或一个隐式计算结果为 `TIMESTAMP` 类型的表达式。

## 返回类型
<a name="r_TIMESTAMPTZ_CMP_TIMESTAMP-return-type"></a>

INTEGER

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

以下示例将带有时区的时间戳与时间戳进行比较，并显示比较结果。

```
SELECT TIMESTAMPTZ_CMP_TIMESTAMP('2008-01-24 06:43:29+00', '2008-01-24 06:43:29'), TIMESTAMPTZ_CMP_TIMESTAMP('2008-01-24 06:43:29+00', '2008-02-18 02:36:48'), TIMESTAMPTZ_CMP_TIMESTAMP('2008-02-18 02:36:48+00', '2008-01-24 06:43:29');

timestamptz_cmp_timestamp  | timestamptz_cmp_timestamp | timestamptz_cmp_timestamp
---------------------------+---------------------------+---------------------------
              0            |            -1             |             1
```

# TIMEZONE 函数
<a name="r_TIMEZONE"></a>

TIMEZONE 返回指定时区的一个时间戳和时间戳值。

有关如何设置时区的信息和示例，请参阅[timezone](r_timezone_config.md)。

有关如何转换时区的信息和示例，请参阅[CONVERT\$1TIMEZONE](CONVERT_TIMEZONE.md)。

## 语法
<a name="r_TIMEZONE-syntax"></a>

```
TIMEZONE('timezone', { timestamp | timestamptz })
```

## 参数
<a name="r_TIMEZONE-arguments"></a>

*timezone*  
返回值的时区。该时区可以指定为时区名称（例如 **'Africa/Kampala'** 或者 **'Singapore'**）或作为时区缩写（例如 **'UTC'** 或者 **'PDT'**）。要查看支持的时区名称的列表，请执行以下命令。  

```
select pg_timezone_names();
```
 要查看支持的时区缩写的列表，请执行以下命令。  

```
select pg_timezone_abbrevs();
```
请注意，Amazon Redshift 使用 [IANA 时区数据库](https://www.iana.org/time-zones)作为时区规范的权威来源。有关更多信息以及示例，请参阅 [时区使用说明](CONVERT_TIMEZONE.md#CONVERT_TIMEZONE-usage-notes)。

*timestamp* \$1 *timestamptz*  
一个结果是 TIMESTAMP 或 TIMESTAMPTZ 类型的表达式，或可隐式强制转换为时间戳或带有时区的时间戳的值。

## 返回类型
<a name="r_TIMEZONE-return-type"></a>

与 TIMESTAMP 表达式一起使用时的 TIMESTAMPTZ。

与 TIMESTAMPTZ 表达式一起使用时的 TIMESTAMP。

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

以下示例使用 PST 时区中的时间戳 `2008-06-17 09:44:54` 返回 UTC 时区的时间戳。

```
SELECT TIMEZONE('PST', '2008-06-17 09:44:54');

timezone
-----------------------
2008-06-17 17:44:54+00
```

以下示例使用带有 UTC 时区的时间戳 `2008-06-17 09:44:54+00` 返回 PST 时区的时间戳。

```
SELECT TIMEZONE('PST', timestamptz('2008-06-17 09:44:54+00'));

timezone
-----------------------
2008-06-17 01:44:54
```

# TO\$1TIMESTAMP 函数
<a name="r_TO_TIMESTAMP"></a>

TO\$1TIMESTAMP 将 TIMESTAMP 字符串转换为 TIMESTAMPTZ。有关适用于 Amazon Redshift 的其他日期和时间函数的列表，请参阅[日期和时间函数](Date_functions_header.md)。

## 语法
<a name="r_TO_TIMESTAMP-syntax"></a>

```
to_timestamp(timestamp, format)
```

```
to_timestamp (timestamp, format, is_strict)
```

## 参数
<a name="r_TO_TIMESTAMP-arguments"></a>

*timestamp*  
以 *format* 指定的格式表示时间戳值的字符串。如果将此参数留为空，则时间戳值默认为 `0001-01-01 00:00:00`。

*format*  
一个字符串文本，用于定义 *timestamp* 值的格式。包含时区的格式（**TZ**、**tz**，或者 **OF**）不支持作为输入。有关有效的时间戳格式，请参阅[日期时间格式字符串](r_FORMAT_strings.md)。

*is\$1strict*  
一个可选的布尔值，它指定在输入时间戳值超出范围时是否返回错误。当 *is\$1strict* 被设置为 TRUE 时，如果存在超出范围的值，则返回错误。当 *is\$1strict* 被设置为 FALSE（默认值）时，则接受溢出值。

## 返回类型
<a name="r_TO_TIMESTAMP-return-type"></a>

TIMESTAMPTZ

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

以下示例演示使用 TO\$1TIMESTAMP 函数将 TIMESTAMP 字符串转换为 TIMESTAMPTZ。

```
select sysdate, to_timestamp(sysdate, 'YYYY-MM-DD HH24:MI:SS') as second;

timestamp                  | second
--------------------------   ----------------------
2021-04-05 19:27:53.281812 | 2021-04-05 19:27:53+00
```

可以传递日期的 TO\$1TIMESTAMP 部分。其余日期部分设置为默认值。时间包括在输出中：

```
SELECT TO_TIMESTAMP('2017','YYYY');

to_timestamp
--------------------------
2017-01-01 00:00:00+00
```

以下 SQL 语句将字符串“2011-12-18 24:38:15”转换为 TIMESTAMPTZ。得到的结果是第二天的 TIMESTAMPTZ，因为小时数超过 24 小时：

```
SELECT TO_TIMESTAMP('2011-12-18 24:38:15', 'YYYY-MM-DD HH24:MI:SS');
         
to_timestamp
----------------------
2011-12-19 00:38:15+00
```

以下 SQL 语句将字符串“2011-12-18 24:38:15”转换为 TIMESTAMPTZ。结果产生错误，因为时间戳中的时间值超过 24 小时：

```
SELECT TO_TIMESTAMP('2011-12-18 24:38:15', 'YYYY-MM-DD HH24:MI:SS', TRUE);
         
ERROR:  date/time field time value out of range: 24:38:15.0
```

# TRUNC 函数
<a name="r_TRUNC_date"></a>

截断 `TIMESTAMP` 并返回 `DATE`。

 此函数也可以截断数值。有关更多信息，请参阅 [TRUNC 函数](r_TRUNC.md)。

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

```
TRUNC(timestamp)
```

## 参数
<a name="r_TRUNC_date-arguments"></a>

 *timestamp*   
数据类型为 `TIMESTAMP` 的列，或一个隐式计算结果为 `TIMESTAMP` 类型的表达式。  
要返回以 `00:00:00` 作为时间的时间戳值，请将函数结果强制转换为 `TIMESTAMP`。

## 返回类型
<a name="r_TRUNC_date-return-type"></a>

DATE

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

以下示例返回 SYSDATE 函数（返回时间戳）的结果的日期部分。

```
SELECT SYSDATE;

+----------------------------+
|         timestamp          |
+----------------------------+
| 2011-07-21 10:32:38.248109 |
+----------------------------+

SELECT TRUNC(SYSDATE);

+------------+
|   trunc    |
+------------+
| 2011-07-21 |
+------------+
```

以下示例将 TRUNC 函数应用于 `TIMESTAMP` 列。返回类型为日期。

```
SELECT TRUNC(starttime) FROM event
ORDER BY eventid LIMIT 1;

+------------+
|   trunc    |
+------------+
| 2008-01-25 |
+------------+
```

以下示例通过将 TRUNC 函数结果强制转换为 `TIMESTAMP` 来返回时间戳值，其中 `00:00:00` 为时间。

```
SELECT CAST((TRUNC(SYSDATE)) AS TIMESTAMP);

+---------------------+
|        trunc        |
+---------------------+
| 2011-07-21 00:00:00 |
+---------------------+
```

# 日期或时间戳函数的日期部分
<a name="r_Dateparts_for_datetime_functions"></a>

下表标识了作为以下函数参数接受的日期部分和时间部分的名称和缩写：
+ DATEADD 
+ DATEDIFF 
+ DATE\$1PART 
+ EXTRACT 

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Dateparts_for_datetime_functions.html)

## 秒、毫秒和微秒导致的结果差异
<a name="r_Dateparts_for_datetime_functions-variations-in-results"></a>

当不同的日期函数指定秒、毫秒或微秒作为日期部分时，查询结果会出现细微差异：
+ EXTRACT 函数仅返回指定日期部分的整数，忽略较高级别和较低级别的日期部分。如果指定的日期部分为秒，则结果中不包括毫秒和微秒。如果指定的日期部分为毫秒，则不包括秒和微秒。如果指定的日期部分为微秒，则不包括秒和毫秒。
+ DATE\$1PART 函数返回时间戳的完整秒部分，无论指定的日期部分是什么，从而根据需要返回十进制值或整数。

例如，比较以下查询的结果：

```
create table seconds(micro timestamp);

insert into seconds values('2009-09-21 11:10:03.189717');

select extract(sec from micro) from seconds;
               
date_part
-----------
3
               
select date_part(sec, micro) from seconds;
   
pgdate_part
-------------
3.189717
```

## CENTURY、EPOCH、DECADE 和 MIL 说明
<a name="r_Dateparts_for_datetime_functions-century"></a>

CENTURY 或 CENTURIES   
Amazon Redshift 将 CENTURY 解释为开始于 *\$1\$1\$11* 年并结束于 `###0` 年：  

```
select extract (century from timestamp '2000-12-16 12:21:13');
date_part
-----------
20

select extract (century from timestamp '2001-12-16 12:21:13');
date_part
-----------
21
```

EPOCH   
Amazon Redshift 的 EPOCH 实施与独立于集群所在的时区的 1970-01-01 00:00:00.000000 相关。根据集群所在的时区，您可能需要按小时差来抵消结果。  
 以下示例演示了以下操作：  

1.  基于 EVENT 表创建名为 EVENT\$1EXAMPLE 的表。此 CREATE AS 命令使用 DATE\$1PART 函数创建日期列（预设情况下称为 PGDATE\$1PART），以存储每个事件的纪元值。

1.  从 PG\$1TABLE\$1DEF 中选择 EVENT\$1EXAMPLE 的列和数据类型。

1.  从 EVENT\$1EXAMPLE 表中选择 EVENTNAME、STARTTIME 和 PGDATE\$1PART，以查看不同的日期和时间格式。

1.  按原样从 EVENT EXAMPLE 中选择 EVENTNAME 和 STARTTIME。使用 1 秒的时间间隔将 PGDATE\$1PART 中的周期值转换为不带时区的时间戳，并在名为 CONVERTED\$1TIMESTAMP 的列中返回结果。

```
create table event_example
as select eventname, starttime, date_part(epoch, starttime) from event;

select "column", type from pg_table_def where tablename='event_example';

     column    |            type
---------------+-----------------------------
 eventname     | character varying(200)
 starttime     | timestamp without time zone
 pgdate_part   | double precision
(3 rows)
```

```
select eventname, starttime, pgdate_part from event_example;

   eventname          |      starttime      | pgdate_part
----------------------+---------------------+-------------
 Mamma Mia!           | 2008-01-01 20:00:00 |  1199217600
 Spring Awakening     | 2008-01-01 15:00:00 |  1199199600
 Nas                  | 2008-01-01 14:30:00 |  1199197800
 Hannah Montana       | 2008-01-01 19:30:00 |  1199215800
 K.D. Lang            | 2008-01-01 15:00:00 |  1199199600
 Spamalot             | 2008-01-02 20:00:00 |  1199304000
 Macbeth              | 2008-01-02 15:00:00 |  1199286000
 The Cherry Orchard   | 2008-01-02 14:30:00 |  1199284200
 Macbeth              | 2008-01-02 19:30:00 |  1199302200
 Demi Lovato          | 2008-01-02 19:30:00 |  1199302200

   
select eventname, 
starttime, 
timestamp with time zone 'epoch' + pgdate_part * interval '1 second' AS converted_timestamp 
from event_example;

       eventname      |      starttime      | converted_timestamp
----------------------+---------------------+---------------------
 Mamma Mia!           | 2008-01-01 20:00:00 | 2008-01-01 20:00:00
 Spring Awakening     | 2008-01-01 15:00:00 | 2008-01-01 15:00:00
 Nas                  | 2008-01-01 14:30:00 | 2008-01-01 14:30:00
 Hannah Montana       | 2008-01-01 19:30:00 | 2008-01-01 19:30:00
 K.D. Lang            | 2008-01-01 15:00:00 | 2008-01-01 15:00:00
 Spamalot             | 2008-01-02 20:00:00 | 2008-01-02 20:00:00
 Macbeth              | 2008-01-02 15:00:00 | 2008-01-02 15:00:00
 The Cherry Orchard   | 2008-01-02 14:30:00 | 2008-01-02 14:30:00
 Macbeth              | 2008-01-02 19:30:00 | 2008-01-02 19:30:00
 Demi Lovato          | 2008-01-02 19:30:00 | 2008-01-02 19:30:00
 ...
```

DECADE 或 DECADES   
Amazon Redshift 根据公历解释 DECADE 或 DECADES DATEPART。例如，由于公历从第一年开始，因此第一个十年（第 1 个十年）是 0001-01-01 到 0009-12-31，而第二个十年（第 2 个十年）是 0010-01-01 到 0019-12-31。例如，十年 201 为 2000-01-01 - 2009-12-31：  

```
select extract(decade from timestamp '1999-02-16 20:38:40');
date_part
-----------
200

select extract(decade from timestamp '2000-02-16 20:38:40');
date_part
-----------
201

select extract(decade from timestamp '2010-02-16 20:38:40');
date_part
-----------
202
```

MIL 或 MILS   
Amazon Redshift 将 MIL 解释为开始于 *\$1001* 年的第一天并结束于 `#000` 年的最后一天：  

```
select extract (mil from timestamp '2000-12-16 12:21:13');
date_part
-----------
2

select extract (mil from timestamp '2001-12-16 12:21:13');
date_part
-----------
3
```

# 哈希函数
<a name="hash-functions"></a>

**Topics**
+ [CHECKSUM 函数](r_CHECKSUM.md)
+ [farmFingerprint64 函数](r_FARMFINGERPRINT64.md)
+ [FUNC\$1SHA1 函数](FUNC_SHA1.md)
+ [FNV\$1HASH 函数](r_FNV_HASH.md)
+ [MD5 函数](r_MD5.md)
+ [SHA 函数](SHA.md)
+ [SHA1 函数](SHA1.md)
+ [SHA2 函数](SHA2.md)
+ [MURMUR3\$132\$1HASH](MURMUR3_32_HASH.md)

哈希函数是将数值输入值转换为另一个值的数学函数。

# CHECKSUM 函数
<a name="r_CHECKSUM"></a>

计算用于建立哈希索引的校验和值。

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

```
CHECKSUM(expression)
```

## 参数
<a name="r_CHECKSUM-argument"></a>

 *expression*   
输入表达式必须是 VARCHAR、INTEGER 或 DECIMAL 数据类型。

## 返回类型
<a name="r_CHECKSUM-return-type"></a>

CHECKSUM 函数返回整数。

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

以下示例计算 COMMISSION 列的校验和值：

```
select checksum(commission)
from sales
order by salesid
limit 10;

checksum
----------
10920
1140
5250
2625
2310
5910
11820
2955
8865
975
(10 rows)
```

# farmFingerprint64 函数
<a name="r_FARMFINGERPRINT64"></a>

使用 `Fingerprint64` 函数计算输入参数的 farmhash 值。

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

```
farmFingerprint64(expression)
```

## 参数
<a name="r_FARMFINGERPRINT64-argument"></a>

 *expression*   
输入表达式必须为 `VARCHAR` 或 `VARBYTE` 数据类型。

## 返回类型
<a name="r_FARMFINGERPRINT64-return-type"></a>

`farmFingerprint64` 函数返回 `BIGINT`。

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

以下示例返回 `Amazon Redshift` 的作为 `VARCHAR` 数据类型输入的 `farmFingerprint64` 值。

```
SELECT farmFingerprint64('Amazon Redshift');
```

```
  
  farmfingerprint64
---------------------
 8085098817162212970
```

以下示例返回 `Amazon Redshift` 的作为 `VARBYTE` 数据类型输入的 `farmFingerprint64` 值。

```
SELECT farmFingerprint64('Amazon Redshift'::varbyte);
```

```
  
  farmfingerprint64
---------------------
 8085098817162212970
```

# FUNC\$1SHA1 函数
<a name="FUNC_SHA1"></a>

SHA1 函数的同义词。

请参阅 [SHA1 函数](SHA1.md)。

# FNV\$1HASH 函数
<a name="r_FNV_HASH"></a>

计算所有基本数据类型的 64 位 FNV-1a 非加密哈希函数。

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

```
FNV_HASH(value [, seed])
```

## 参数
<a name="r_FNV_HASH-argument-arguments"></a>

 *值*  
要进行哈希处理的输入值。Amazon Redshift 使用值的二进制表示形式来对输入值进行哈希处理；例如，使用 4 个字节对 INTEGER 值进行哈希处理，使用 8 个字节对 BIGINT 值进行哈希处理。此外，对 CHAR 和 VARCHAR 输入进行哈希处理不会忽略尾随空格。

 *种子*  
哈希函数的 BIGINT 种子是可选的。如果未给定，Amazon Redshift 使用默认 FNV 种子。这样可以组合多个列的哈希，而无需任何转换或联接。

## 返回类型
<a name="r_FNV_HASH-return-type"></a>

BIGINT

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

以下示例返回数字的 FNV 哈希值、字符串“Amazon Redshift”以及两者的联接。

```
select fnv_hash(1);
        fnv_hash
----------------------
 -5968735742475085980
(1 row)
```

```
select fnv_hash('Amazon Redshift');
      fnv_hash
---------------------
 7783490368944507294
(1 row)
```

```
select fnv_hash('Amazon Redshift', fnv_hash(1));
       fnv_hash
----------------------
 -2202602717770968555
(1 row)
```

## 使用说明
<a name="r_FNV_HASH-usage-notes"></a>
+ 要计算具有多列的表的哈希，可以计算第一列的 FNV 哈希，并将其作为种子传递给第二列的哈希。然后，它将第二列的 FNV 哈希作为种子传递给第三列的哈希。

  以下示例创建种子来对包含多列的表进行哈希处理。

  ```
  select fnv_hash(column_3, fnv_hash(column_2, fnv_hash(column_1))) from sample_table;
  ```
+ 同一个属性可用于计算字符串联接的哈希。

  ```
  select fnv_hash('abcd');
         fnv_hash
  ---------------------
   -281581062704388899
  (1 row)
  ```

  ```
  select fnv_hash('cd', fnv_hash('ab'));
        fnv_hash
  ---------------------
   -281581062704388899
  (1 row)
  ```
+ 哈希函数使用输入的类型来确定要进行哈希处理的字节数。如有必要，使用强制转换来强制特定类型。

  以下示例使用不同类型的输入来生成不同的结果。

  ```
  select fnv_hash(1::smallint);
        fnv_hash
  --------------------
   589727492704079044
  (1 row)
  ```

  ```
  select fnv_hash(1);
         fnv_hash
  ----------------------
   -5968735742475085980
  (1 row)
  ```

  ```
  select fnv_hash(1::bigint);
         fnv_hash
  ----------------------
   -8517097267634966620
  (1 row)
  ```

# MD5 函数
<a name="r_MD5"></a>

使用 MD5 加密哈希函数将长度可变的字符串转换为以 128 位校验和的十六进制值的文本表示形式表示的 32 字符字符串。

## 语法
<a name="r_MD5-syntax"></a>

```
MD5(string)
```

## 参数
<a name="r_MD5-arguments"></a>

 *string*   
一个长度可变的字符串。

## 返回类型
<a name="r_MD5-return-type"></a>

MD5 函数返回以 128 位校验和的十六进制值的文本表示形式表示的 32 字符字符串。

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

以下示例显示了字符串“Amazon Redshift”的 128 位值：

```
select md5('Amazon Redshift');
md5
----------------------------------
f7415e33f972c03abd4f3fed36748f7a
(1 row)
```

# SHA 函数
<a name="SHA"></a>

SHA1 函数的同义词。

请参阅 [SHA1 函数](SHA1.md)。

# SHA1 函数
<a name="SHA1"></a>

SHA1 函数使用 SHA1 加密哈希函数将长度可变的字符串转换为以 160 位校验和的十六进制值的文本表示形式表示的 40 个字符的字符串。

## 语法
<a name="SHA1-syntax"></a>

SHA1 是 [SHA 函数](SHA.md) 和 [FUNC\$1SHA1 函数](FUNC_SHA1.md) 的同义词。

```
SHA1(string)
```

## 参数
<a name="SHA1-arguments"></a>

 *string*   
一个长度可变的字符串。

## 返回类型
<a name="SHA1-returm-type"></a>

SHA1 函数返回以 160 位校验和的十六进制值的文本表示形式表示的 40 个字符的字符串。

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

以下示例返回单词“Amazon Redshift”的 160 位值：

```
select sha1('Amazon Redshift');
```

# SHA2 函数
<a name="SHA2"></a>

SHA2 函数使用 SHA2 加密哈希函数将长度可变的字符串转换为一个字符串。该字符串是具有指定位数的校验和的十六进制值的文本表示形式。

## 语法
<a name="SHA2-syntax"></a>

```
SHA2(string, bits)
```

## 参数
<a name="SHA2-arguments"></a>

 *string*   
一个长度可变的字符串。

 *integer*   
哈希函数中的位数。有效值为 0（与 256 相同）、224、256、384 和 512。

## 返回类型
<a name="SHA2-returm-type"></a>

SHA2 函数返回一个字符串，该字符串是校验和的十六进制值的文本表示形式；如果位数无效，此函数将返回一个空字符串。

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

以下示例返回单词“Amazon Redshift”的 256 位值：

```
select sha2('Amazon Redshift', 256);
```

# MURMUR3\$132\$1HASH
<a name="MURMUR3_32_HASH"></a>

MURMUR3\$132\$1HASH 函数计算包括数值和字符串类型在内的所有常见数据类型的 32 位 Murmur3A 非加密哈希。

## 语法
<a name="MURMUR3_32_HASH-syntax"></a>

```
MURMUR3_32_HASH(value [, seed])
```

## 参数
<a name="MURMUR3_32_HASH-arguments"></a>

 *值*   
要进行哈希处理的输入值。Amazon Redshift 对输入值的二进制表示进行哈希处理。此行为类似于 [FNV\$1HASH 函数](r_FNV_HASH.md)，但值会转换为由 [Apache Iceberg 32 位 Murmur3 哈希规范](https://iceberg.apache.org/spec/#appendix-b-32-bit-hash-requirements)指定的二进制表示形式。

 *%seed*   
哈希函数的 INT 种子。此参数是可选的。如果未给定，Amazon Redshift 使用默认种子 0。这样可以组合多个列的哈希，而无需任何转换或联接。

## 返回类型
<a name="MURMUR3_32_HASH-return-type"></a>

此函数返回 INT。

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

以下示例分别返回数字、字符串“Amazon Redshift”以及两者的联接的 Murmur3 哈希值。

```
select MURMUR3_32_HASH(1);
    
    MURMUR3_32_HASH
----------------------
 1392991556
(1 row)
```

```
select MURMUR3_32_HASH('Amazon Redshift');
    
    MURMUR3_32_HASH
----------------------
 -1563580564
(1 row)
```

```
select MURMUR3_32_HASH('Amazon Redshift', MURMUR3_32_HASH(1));
    
    MURMUR3_32_HASH
----------------------
 -1346554171
(1 row)
```

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

要计算具有多列的表的哈希，可以计算第一列的 Murmur3 哈希，并将其作为种子传递给第二列的哈希。然后，它将第二列的 Murmur3 哈希作为种子传递给第三列的哈希。

以下示例创建种子来对包含多列的表进行哈希处理。

```
select MURMUR3_32_HASH(column_3, MURMUR3_32_HASH(column_2, MURMUR3_32_HASH(column_1))) from sample_table;
```

同一个属性可用于计算字符串联接的哈希。

```
select MURMUR3_32_HASH('abcd');
   
   MURMUR3_32_HASH
---------------------
 1139631978
(1 row)
```

```
select MURMUR3_32_HASH('cd', MURMUR3_32_HASH('ab'));
   
   MURMUR3_32_HASH
---------------------
 1711522338
(1 row)
```

哈希函数使用输入的类型来确定要进行哈希处理的字节数。如有必要，使用强制转换来强制特定类型。

以下示例使用不同的输入类型来生成不同的结果。

```
select MURMUR3_32_HASH(1, MURMUR3_32_HASH(1));
   
   MURMUR3_32_HASH
--------------------
 -1193428387
(1 row)
```

```
select MURMUR3_32_HASH(1);
   
   MURMUR3_32_HASH
----------------------
 1392991556
(1 row)
```

```
select MURMUR3_32_HASH(1, MURMUR3_32_HASH(2));
   
   MURMUR3_32_HASH
----------------------
 1179621905
(1 row)
```

# HyperLogLog 函数
<a name="hyperloglog-functions"></a>

接下来，您可以找到 Amazon Redshift 支持的 HyperLogLog 函数的描述。

**Topics**
+ [HLL 函数](r_HLL_function.md)
+ [HLL\$1CREATE\$1SKETCH 函数](r_HLL_CREATE_SKETCH.md)
+ [HLL\$1CARDINALITY 函数](r_HLL_CARDINALITY.md)
+ [HLL\$1COMBINE 函数](r_HLL_COMBINE.md)
+ [HLL\$1COMBINE\$1SKETCHES 函数](r_HLL_COMBINE_SKETCHES.md)

# HLL 函数
<a name="r_HLL_function"></a>

HLL 函数返回输入表达式值的 HyperLogLog 基数。HLL 函数适用于除 HLLSKETCH 数据类型之外的任何数据类型。HLL 函数将忽略 NULL 值。如果表中没有行或所有行均为 NULL，则生成的基数为 0。

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

```
HLL (aggregate_expression)
```

## 参数
<a name="r_HLL_function-argument"></a>

 *aggregate\$1expression*   
将值提供给聚合的任何有效表达式（如列名称）。此函数支持除 HLLSKETCH、GEOMETRY、GEOGRAPHY 和 VARBYTE 之外的任何数据类型作为输入。

## 返回类型
<a name="r_HLL_function-return-type"></a>

HLL 函数返回一个 BIGINT 或 INT8 值。

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

以下示例返回表 `a_table` 中列 `an_int` 的基数。

```
CREATE TABLE a_table(an_int INT);
INSERT INTO a_table VALUES (1), (2), (3), (4);

SELECT hll(an_int) AS cardinality FROM a_table;
cardinality
-------------
4
```

# HLL\$1CREATE\$1SKETCH 函数
<a name="r_HLL_CREATE_SKETCH"></a>

HLL\$1CREATE\$1SKETCH 函数返回封装输入表达式值的 HLLSKETCH 数据类型。HLL\$1CREATE\$1SKETCH 函数适用于任何数据类型，并忽略 NULL 值。如果表中没有行或所有行都为 NULL，则生成的草图没有 `{"version":1,"logm":15,"sparse":{"indices":[],"values":[]}}` 之类的索引值对。

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

```
HLL_CREATE_SKETCH (aggregate_expression)
```

## 参数
<a name="r_HLL_CREATE_SKETCH-argument"></a>

 *aggregate\$1expression*   
将值提供给聚合的任何有效表达式（如列名称）。将忽略 NULL 值。此函数支持除 HLLSKETCH、GEOMETRY、GEOGRAPHY 和 VARBYTE 之外的任何数据类型作为输入。

## 返回类型
<a name="r_HLL_CREATE_SKETCH-return-type"></a>

HLL\$1CREATE\$1SKETCH 函数返回一个 HLLSKETCH 值。

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

以下示例返回表 `a_table` 中列 `an_int` 的 HLLSKETCH 类型。在导入、导出或打印草图时，JSON 对象用于表示稀疏的 HyperLogLog 草图。字符串表示形式（Base64 格式）用于表示密集的 HyperLogLog 草图。

```
CREATE TABLE a_table(an_int INT);
INSERT INTO a_table VALUES (1), (2), (3), (4);

SELECT hll_create_sketch(an_int) AS sketch FROM a_table;
sketch
-------------------------------------------------------------------------------------------------------
{"version":1,"logm":15,"sparse":{"indices":[20812342,20850007,22362299,47158030],"values":[1,2,1,1]}}
(1 row)
```

# HLL\$1CARDINALITY 函数
<a name="r_HLL_CARDINALITY"></a>

HLL\$1CARDINALITY 函数返回输入 HLLSKETCH 数据类型的基数。

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

```
HLL_CARDINALITY (hllsketch_expression)
```

## 参数
<a name="r_HLL_CARDINALITY-argument"></a>

 *hllsketch\$1expression*   
计算结果为 HLLSKETCH 类型的任何有效表达式（如列名称）。输入值为 HLLSKETCH 数据类型。

## 返回类型
<a name="r_HLL_CARDINALITY-return-type"></a>

HLL\$1CARDINALITY 函数返回一个 BIGINT 或 INT8 值。

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

以下示例返回表 `hll_table` 中列 `sketch` 的基数。

```
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;

SELECT hll_cardinality(sketch) AS cardinality FROM hll_table;
cardinality
-------------
6
4
(2 rows)
```

# HLL\$1COMBINE 函数
<a name="r_HLL_COMBINE"></a>

HLL\$1COMBINE 聚合函数返回一个 HLLSKETCH 数据类型，该数据类型将所有的输入 HLLSKETCH 值合并。

两个或多个 HyperLogLog 草图的组合是一个新的 HLLSKETCH，它封装了有关每个输入草图所表示的不同值的并集的信息。合并草图后，Amazon Redshift 会提取两个或多个数据集的并集的基数。有关如何合并多个草图的更多信息，请参阅[示例：通过合并多个草图返回 HyperLogLog 草图](r_HLL-examples.md#hll-examples-multiple-sketches)。

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

```
HLL_COMBINE (hllsketch_expression)
```

## 参数
<a name="r_HLL_COMBINE-argument"></a>

 *hllsketch\$1expression*   
计算结果为 HLLSKETCH 类型的任何有效表达式（如列名称）。输入值为 HLLSKETCH 数据类型。

## 返回类型
<a name="r_HLL_COMBINE-return-type"></a>

HLL\$1COMBINE 函数返回一个 HLLSKETCH 类型。

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

以下示例返回表 `hll_table` 中的合并 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;

SELECT hll_combine(sketch) AS sketches FROM hll_table;
sketches
----------------------------------------------------------------------------------------------------------------------------
{"version":1,"logm":15,"sparse":{"indices":[20812342,20850007,22362299,40314817,42650774,47158030],"values":[1,2,1,3,2,1]}}
(1 row)
```

# HLL\$1COMBINE\$1SKETCHES 函数
<a name="r_HLL_COMBINE_SKETCHES"></a>

HLL\$1COMBINE\$1SKETCHES 是一个标量函数，它将两个 HLLSKETCH 值作为输入，并将它们合并为单个 HLLSKETCH 值。

两个或多个 HyperLogLog 草图的组合是一个新的 HLLSKETCH，它封装了有关每个输入草图所表示的不同值的并集的信息。

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

```
HLL_COMBINE_SKETCHES (hllsketch_expression1, hllsketch_expression2)
```

## 参数
<a name="r_HLL_COMBINE_SKETCHES-argument"></a>

 *hllsketch\$1expression1* 和 *hllsketch\$1expression2*   
计算结果为 HLLSKETCH 类型的任何有效表达式（如列名称）。

## 返回类型
<a name="r_HLL_COMBINE_SKETCHES-return-type"></a>

HLL\$1COMBINE\$1SKETCHES 函数返回一个 HLLSKETCH 类型。

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

以下示例返回表 `hll_table` 中的合并 HLLSKETCH 值。

```
WITH tbl1(x, y)
     AS (SELECT Hll_create_sketch(1),
                Hll_create_sketch(2)
         UNION ALL
         SELECT Hll_create_sketch(3),
                Hll_create_sketch(4)
         UNION ALL
         SELECT Hll_create_sketch(5),
                Hll_create_sketch(6)
         UNION ALL
         SELECT Hll_create_sketch(7),
                Hll_create_sketch(8)),
     tbl2(x, y)
     AS (SELECT Hll_create_sketch(9),
                Hll_create_sketch(10)
         UNION ALL
         SELECT Hll_create_sketch(11),
                Hll_create_sketch(12)
         UNION ALL
         SELECT Hll_create_sketch(13),
                Hll_create_sketch(14)
         UNION ALL
         SELECT Hll_create_sketch(15),
                Hll_create_sketch(16)
         UNION ALL
         SELECT Hll_create_sketch(NULL),
                Hll_create_sketch(NULL)),
     tbl3(x, y)
     AS (SELECT *
         FROM   tbl1
         UNION ALL
         SELECT *
         FROM   tbl2)
SELECT Hll_combine_sketches(x, y)
FROM   tbl3;
```

# JSON 函数
<a name="json-functions"></a>

**Topics**
+ [JSON\$1PARSE 函数](JSON_PARSE.md)
+ [CAN\$1JSON\$1PARSE 函数](CAN_JSON_PARSE.md)
+ [JSON\$1SERIALIZE 函数](JSON_SERIALIZE.md)
+ [JSON\$1SERIALIZE\$1TO\$1VARBYTE 函数](JSON_SERIALIZE_TO_VARBYTE.md)
+ [基于文本的 JSON 函数](text-json-functions.md)

**注意**  
我们建议您使用以下函数来处理 JSON：  
 [JSON\$1PARSE 函数](JSON_PARSE.md) 
 [CAN\$1JSON\$1PARSE 函数](CAN_JSON_PARSE.md) 
 [JSON\$1SERIALIZE 函数](JSON_SERIALIZE.md) 
 [JSON\$1SERIALIZE\$1TO\$1VARBYTE 函数](JSON_SERIALIZE_TO_VARBYTE.md) 
使用 JSON\$1PARSE，您只需要在摄取时将 JSON 文本转换为 SUPER 类型值一次，之后就可以对 SUPER 值进行操作了。Amazon Redshift 解析 SUPER 值的效率比 VARCHAR 更高，后者是基于文本的 JSON 函数的输出。有关处理 SUPER 数据类型的更多信息，请参阅[Amazon Redshift 中的半结构化数据](super-overview.md)。

当您需要存储相对较小的一组键值对时，您可以通过以 JSON 格式存储数据来节省空间。由于 JSON 字符串可存储在单个列中，因此使用 JSON 可能比以表格格式存储数据更高效。例如，假设您有一个稀疏表，在此表中，您需要设置多个列来完整表示所有可能的属性，但大多数列值对任何给定行或任何给定列为 NULL。通过将 JSON 用于存储，您可能能够将行的数据以键值对的形式存储在单个 JSON 字符串中并删除稀疏填充的表列。

此外，当 JSON 架构发生变化时，您还可以轻松修改 JSON 字符串来存储其它键值对，而无需向表添加列。

我们建议慎用 JSON。若要存储较大的数据集，JSON 不是一个好的选择，因为将分散的数据存储在单个列中后，JSON 不会利用 Amazon Redshift 的列存储架构。虽然 Amazon Redshift 支持跨 CHAR 和 VARCHAR 列的 JSON 函数，但我们建议使用 SUPER 来处理 JSON 序列化格式的数据。SUPER 使用可以有效查询分层数据的后解析无 schema 表示。有关 SUPER 数据类型的更多信息，请参阅[Amazon Redshift 中的半结构化数据](super-overview.md)。

JSON 使用 UTF-8 编码的文本字符串，因此 JSON 字符串可存储为 CHAR 或 VARCHAR 数据类型。

JSON 字符串必须是根据以下规则正确设置格式的 JSON：
+ 根级别的 JSON 可以是 JSON 对象或 JSON 数组。JSON 对象是用大括号括起的一组无序的键值对（由逗号分隔）。

  例如，`{"one":1, "two":2} `
+ JSON 数组是用方括号括起的一组有序值（由逗号分隔）。

  以下是示例：`["first", {"one":1}, "second", 3, null] `
+ JSON 数组使用从零开始的索引；数组中的第一个元素位于位置 0。在 JSON 键:值对中，键是用双引号括起的字符串。
+ JSON 值可能为以下任一值：
  + JSON 对象 
  + 数组 
  + 字符串
    + 用双引号表示
  + 数字
    + 包括整数、小数和浮点数
  + 布尔值
  + null 
+ 空对象和空数组是有效的 JSON 值。
+ JSON 字段区分大小写。
+ 将忽略 JSON 结构元素之间的空格（如 `{ }, [ ]`）。

Amazon Redshift JSON 函数和 Amazon Redshift COPY 命令使用相同的方法处理 JSON 格式的数据。有关使用 JSON 的更多信息，请参阅[从 JSON 格式数据执行的 COPY 操作](copy-usage_notes-copy-from-json.md)。

# JSON\$1PARSE 函数
<a name="JSON_PARSE"></a>

JSON\$1PARSE 函数以 JSON 格式解析数据并将其转换为 `SUPER` 表示形式。

要使用 INSERT 或 UPDATE 命令摄取到 `SUPER` 数据类型，请使用 JSON\$1PARSE 函数。当您使用 JSON\$1PARSE () 将 JSON 字符串解析为 `SUPER` 值时，某些限制适用。有关更多信息，请参阅 [解析 SUPER 的选项](super-configurations.md#parsing-options-super)。

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

```
JSON_PARSE( {json_string | binary_value} )
```

## 参数
<a name="JSON_PARSE-arguments"></a>

 *json\$1string*  
以 `VARBYTE` 或 `VARCHAR` 类型返回序列化 JSON 的表达式。

 *binary\$1value*  
VARBYTE 类型的二进制值。

## 返回类型
<a name="JSON_PARSE-return"></a>

`SUPER`

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

要将 JSON 数组 `[10001,10002,"abc"]` 转换为 `SUPER` 数据类型，请使用以下示例。

```
SELECT JSON_PARSE('[10001,10002,"abc"]');

+---------------------+
|     json_parse      |
+---------------------+
| [10001,10002,"abc"] |
+---------------------+
```

为了确保函数将 JSON 数组转换为 `SUPER` 数据类型，请使用以下示例。有关更多信息，请参阅 [JSON\$1TYPEOF 函数](r_json_typeof.md)。

```
SELECT JSON_TYPEOF(JSON_PARSE('[10001,10002,"abc"]'));

+-------------+
| json_typeof |
+-------------+
| array       |
+-------------+
```

# CAN\$1JSON\$1PARSE 函数
<a name="CAN_JSON_PARSE"></a>

CAN\$1JSON\$1PARSE 函数以 JSON 格式解析数据，如果可以使用 JSON\$1PARSE 函数将结果转换为 `SUPER` 值，则返回 `true`。

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

```
CAN_JSON_PARSE( {json_string | binary_value} )
```

## 参数
<a name="CAN_JSON_PARSE-arguments"></a>

 *json\$1string*  
以 `VARCHAR` 形式返回序列化 JSON 的表达式。

 *binary\$1value*  
VARBYTE 类型的二进制值。

## 返回类型
<a name="CAN_JSON_PARSE-return"></a>

`BOOLEAN`

## 使用说明
<a name="CAN_JSON_PARSE-usage-notes"></a>
+ CAN\$1JSON\$1PARSE 对于空字符串返回 false。当输入参数为 null 时，它返回 NULL。

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

 以下示例显示了使用 CASE 条件对格式正确的 JSON 数组运行 CAN\$1JSON\$1PARSE 的情况。它返回 true，因此 Amazon Redshift 对示例值运行 JSON\$1PARSE 函数。

```
SELECT CASE 
            WHEN CAN_JSON_PARSE('[10001,10002,"abc"]')
            THEN JSON_PARSE('[10001,10002,"abc"]')
        END;

 case
---------------------
'[10001,10002,"abc"]'
```

 以下示例显示了使用 CASE 条件对非 JSON 格式的值运行 CAN\$1JSON\$1PARSE 的情况。它返回 false，因此 Amazon Redshift 改为返回 CASE 条件的 ELSE 子句中的段。

```
SELECT CASE 
            WHEN CAN_JSON_PARSE('This is a string.')
            THEN JSON_PARSE('This is a string.')
            ELSE 'This is not JSON.'
        END;

 case
---------------------
"This is not JSON."
```

# JSON\$1SERIALIZE 函数
<a name="JSON_SERIALIZE"></a>

JSON\$1SERIALIZE 函数将 `SUPER` 表达式序列化为文本 JSON 表示形式，以遵守 RFC 8259。有关该 RFC 的更多信息，请参阅 [JavaScript Object Notation (JSON) 数据交换格式](https://tools.ietf.org/html/rfc8259)。

`SUPER` 大小限制与数据块限制大致相同，并且 `VARCHAR` 限制小于 `SUPER` 大小限制。因此，当 JSON 格式超出系统的 VARCHAR 限制时，JSON\$1SERIALIZE 函数会返回一个错误。要检查 `SUPER` 表达式的大小，请参阅 [JSON\$1SIZE](r_json_size.md) 函数。

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

```
JSON_SERIALIZE(super_expression)
```

## 参数
<a name="JSON_SERIALIZE-arguments"></a>

 *super\$1expression*  
`SUPER` 表达式或列。

## 返回类型
<a name="JSON_SERIALIZE-return"></a>

`VARCHAR`

**注意**  
返回的 VARCHAR 值始终为非空 JSON 字符串。如果 *super\$1expression* 为 NULL，则 JSON\$1SERIALIZE 返回 JSON 字符串 `'null'`。

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

要将 `SUPER` 值序列化为字符串，请使用以下示例。

```
SELECT JSON_SERIALIZE(JSON_PARSE('[10001,10002,"abc"]'));
   
+---------------------+
|   json_serialize    |
+---------------------+
| [10001,10002,"abc"] |
+---------------------+
```

# JSON\$1SERIALIZE\$1TO\$1VARBYTE 函数
<a name="JSON_SERIALIZE_TO_VARBYTE"></a>

JSON\$1SERIALIZE\$1TO\$1VARBYTE 函数将 `SUPER` 值转换为类似于 JSON\$1SERIALIZE() 的 JSON 字符串，但存储在 `VARBYTE` 值中。

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

```
JSON_SERIALIZE_TO_VARBYTE(super_expression)
```

## 参数
<a name="JSON_SERIALIZE_TO_VARBYTE-arguments"></a>

 *super\$1expression*  
`SUPER` 表达式或列。

## 返回类型
<a name="JSON_SERIALIZE_TO_VARBYTE-return"></a>

`VARBYTE`

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

要序列化 `SUPER` 值并以 `VARBYTE` 格式返回结果，请使用以下示例。

```
SELECT JSON_SERIALIZE_TO_VARBYTE(JSON_PARSE('[10001,10002,"abc"]'));

+----------------------------------------+
|       json_serialize_to_varbyte        |
+----------------------------------------+
| 5b31303030312c31303030322c22616263225d |
+----------------------------------------+
```

要序列化 `SUPER` 值并将结果强制转换为 `VARCHAR` 格式，请使用以下示例。有关更多信息，请参阅 [CAST 函数](r_CAST_function.md)。

```
SELECT CAST((JSON_SERIALIZE_TO_VARBYTE(JSON_PARSE('[10001,10002,"abc"]'))) AS VARCHAR);

+---------------------------+
| json_serialize_to_varbyte |
+---------------------------+
| [10001,10002,"abc"]       |
+---------------------------+
```

# 基于文本的 JSON 函数
<a name="text-json-functions"></a>

本节中的函数将 JSON 值解析为 VARCHAR。要解析 JSON，我们建议您改用以下函数，这些函数将 JSON 值解析为 SUPER。Amazon Redshift 解析 SUPER 值的效率比 VARCHAR 更高。
+  [JSON\$1PARSE 函数](JSON_PARSE.md) 
+  [CAN\$1JSON\$1PARSE 函数](CAN_JSON_PARSE.md) 
+  [JSON\$1SERIALIZE 函数](JSON_SERIALIZE.md) 
+  [JSON\$1SERIALIZE\$1TO\$1VARBYTE 函数](JSON_SERIALIZE_TO_VARBYTE.md) 

**Topics**
+ [IS\$1VALID\$1JSON 函数](IS_VALID_JSON.md)
+ [IS\$1VALID\$1JSON\$1ARRAY 函数](IS_VALID_JSON_ARRAY.md)
+ [JSON\$1ARRAY\$1LENGTH 函数](JSON_ARRAY_LENGTH.md)
+ [JSON\$1EXTRACT\$1ARRAY\$1ELEMENT\$1TEXT 函数](JSON_EXTRACT_ARRAY_ELEMENT_TEXT.md)
+ [JSON\$1EXTRACT\$1PATH\$1TEXT 函数](JSON_EXTRACT_PATH_TEXT.md)

# IS\$1VALID\$1JSON 函数
<a name="IS_VALID_JSON"></a>

**注意**  
CAN\$1JSON\$1PARSE 及其关联函数将 JSON 值解析为 SUPER，Amazon Redshift 解析 SUPER 的效率比 VARCHAR 更高。  
 我们建议您使用 [CAN\$1JSON\$1PARSE 函数](CAN_JSON_PARSE.md)验证您的 JSON 字符串，而不是使用 IS\$1VALID\$1JSON。

IS\$1VALID\$1JSON 函数用于验证 JSON 字符串。如果字符串是格式正确的 JSON 字符串，则该函数返回布尔值 `true`；如果字符串格式不正确，函数将返回 `false`。要验证 JSON 数组，请使用 [IS\$1VALID\$1JSON\$1ARRAY 函数](IS_VALID_JSON_ARRAY.md)

有关更多信息，请参阅 [JSON 函数](json-functions.md)。

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

```
IS_VALID_JSON('json_string')
```

## 参数
<a name="IS_VALID_JSON-arguments"></a>

 *json\$1string*  
计算结果为 JSON 字符串的字符串或表达式。

## 返回类型
<a name="IS_VALID_JSON-return"></a>

`BOOLEAN`

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

要创建一个表并插入 JSON 字符串进行测试，请使用以下示例。

```
CREATE TABLE test_json(id int IDENTITY(0,1), json_strings VARCHAR);

-- Insert valid JSON strings --
INSERT INTO test_json(json_strings) VALUES
('{"a":2}'), 
('{"a":{"b":{"c":1}}}'), 
('{"a": [1,2,"b"]}');

-- Insert invalid JSON strings --
INSERT INTO test_json(json_strings) VALUES
('{{}}'), 
('{1:"a"}'), 
('[1,2,3]');
```

要验证前面示例中的字符串，请使用下面的示例。

```
SELECT id, json_strings, IS_VALID_JSON(json_strings) 
FROM test_json
ORDER BY id;

+----+---------------------+---------------+
| id |    json_strings     | is_valid_json |
+----+---------------------+---------------+
|  0 | {"a":2}             | true          |
|  4 | {"a":{"b":{"c":1}}} | true          |
|  8 | {"a": [1,2,"b"]}    | true          |
| 12 | {{}}                | false         |
| 16 | {1:"a"}             | false         |
| 20 | [1,2,3]             | false         |
+----+---------------------+---------------+
```

# IS\$1VALID\$1JSON\$1ARRAY 函数
<a name="IS_VALID_JSON_ARRAY"></a>

**注意**  
JSON\$1PARSE 及其关联函数将 JSON 值解析为 SUPER，Amazon Redshift 解析 SUPER 的效率比 VARCHAR 更高。  
 我们建议您使用 [JSON\$1PARSE 函数](JSON_PARSE.md)解析 JSON 字符串来获取 SUPER 值，而不是使用 IS\$1VALID\$1JSON\$1ARRAY。然后，使用 [IS\$1ARRAY 函数](r_is_array.md)来确认数组的格式是否正确。

IS\$1VALID\$1JSON\$1ARRAY 函数用于验证 JSON 数组。如果数组是格式正确的 JSON 数组，则该函数返回布尔值 `true`；如果数组格式不正确，函数将返回 `false`。要验证 JSON 字符串，请使用 [IS\$1VALID\$1JSON 函数](IS_VALID_JSON.md)

有关更多信息，请参阅 [JSON 函数](json-functions.md)。

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

```
IS_VALID_JSON_ARRAY('json_array') 
```

## 参数
<a name="IS_VALID_JSON_ARRAY-arguments"></a>

 *json\$1array*  
计算结果为 JSON 数组的字符串或表达式。

## 返回类型
<a name="IS_VALID_JSON_ARRAY-return"></a>

`BOOLEAN`

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

要创建一个表并插入 JSON 字符串进行测试，请使用以下示例。

```
CREATE TABLE test_json_arrays(id int IDENTITY(0,1), json_arrays VARCHAR);

-- Insert valid JSON array strings --
INSERT INTO test_json_arrays(json_arrays) 
VALUES('[]'), 
('["a","b"]'), 
('["a",["b",1,["c",2,3,null]]]');

-- Insert invalid JSON array strings --
INSERT INTO test_json_arrays(json_arrays) 
VALUES('{"a":1}'),
('a'),
('[1,2,]');
```

要验证前面示例中的字符串，请使用下面的示例。

```
SELECT json_arrays, IS_VALID_JSON_ARRAY(json_arrays) 
FROM test_json_arrays ORDER BY id;

+------------------------------+---------------------+
|         json_arrays          | is_valid_json_array |
+------------------------------+---------------------+
| []                           | true                |
| ["a","b"]                    | true                |
| ["a",["b",1,["c",2,3,null]]] | true                |
| {"a":1}                      | false               |
| a                            | false               |
| [1,2,]                       | false               |
+------------------------------+---------------------+
```

# JSON\$1ARRAY\$1LENGTH 函数
<a name="JSON_ARRAY_LENGTH"></a>

**注意**  
JSON\$1PARSE 及其关联函数将 JSON 值解析为 SUPER，Amazon Redshift 解析 SUPER 的效率比 VARCHAR 更高。  
 我们建议您使用 [JSON\$1PARSE 函数](JSON_PARSE.md)解析 JSON 字符串来获取 SUPER 值，而不是使用 JSON\$1ARRAY\$1LENGTH。然后，使用 [GET\$1ARRAY\$1LENGTH 函数](get_array_length.md)来获取数组的长度。

JSON\$1ARRAY\$1LENGTH 函数返回 JSON 字符串的外部数组中的元素的数量。如果 *null\$1if\$1invalid* 参数设置为 `true` 并且 JSON 字符串无效，函数将返回 `NULL` 而不是返回错误。

有关更多信息，请参阅 [JSON 函数](json-functions.md)。

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

```
JSON_ARRAY_LENGTH('json_array' [, null_if_invalid ] ) 
```

## 参数
<a name="JSON_ARRAY_LENGTH-arguments"></a>

 *json\$1array*  
格式正确的 JSON 数组。

 *null\$1if\$1invalid*  
（可选）一个 `BOOLEAN` 值，指定在输入 JSON 字符串无效时是否返回 `NULL`，而不返回错误。要在 JSON 无效时返回 `NULL`，请指定 `true`（`t`）。要在 JSON 无效时返回错误，请指定 `false` (`f`)。默认为 `false`。

## 返回类型
<a name="JSON_ARRAY_LENGTH-return"></a>

`INTEGER`

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

要返回数组中的元素数，请使用以下示例。

```
SELECT JSON_ARRAY_LENGTH('[11,12,13,{"f1":21,"f2":[25,26]},14]'); 

+-------------------+
| json_array_length |
+-------------------+
|                 5 |
+-------------------+
```

要因为 JSON 无效而返回错误，请使用以下示例。

```
SELECT JSON_ARRAY_LENGTH('[11,12,13,{"f1":21,"f2":[25,26]},14');
 
ERROR: invalid json array object [11,12,13,{"f1":21,"f2":[25,26]},14
```

要将 *null\$1if\$1invalid* 设置为 *true*，以便语句返回 `NULL`，而不是在 JSON 无效时返回错误，请使用以下示例。

```
SELECT JSON_ARRAY_LENGTH('[11,12,13,{"f1":21,"f2":[25,26]},14',true);

+-------------------+
| json_array_length |
+-------------------+
| NULL              |
+-------------------+
```

# JSON\$1EXTRACT\$1ARRAY\$1ELEMENT\$1TEXT 函数
<a name="JSON_EXTRACT_ARRAY_ELEMENT_TEXT"></a>

**注意**  
JSON\$1PARSE 及其关联函数将 JSON 值解析为 SUPER，Amazon Redshift 解析 SUPER 的效率比 VARCHAR 更高。  
我们建议您使用 [JSON\$1PARSE 函数](JSON_PARSE.md)解析 JSON 字符串来获取 SUPER 值，而不是使用 JSON\$1EXTRACT\$1ARRAY\$1ELEMENT\$1TEXT。然后，使用 `value[element position]` 语法，通过其数组索引查询所需的元素。有关在 SUPER 值中查询数组元素的更多信息，请转到[查询半结构化数据](query-super.md)。

JSON\$1EXTRACT\$1ARRAY\$1ELEMENT\$1TEXT 函数返回 JSON 字符串的最外侧数组中的 JSON 数组元素（使用从零开始的索引）。数组中的第一个元素位于位置 0。如果索引为负或超出界限，JSON\$1EXTRACT\$1ARRAY\$1ELEMENT\$1TEXT 将返回 `NULL`。如果 *null\$1if\$1invalid* 参数设置为 `TRUE` 并且 JSON 字符串无效，函数将返回 `NULL` 而不是返回错误。

有关更多信息，请参阅 [JSON 函数](json-functions.md)。

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

```
JSON_EXTRACT_ARRAY_ELEMENT_TEXT('json string', pos [, null_if_invalid ] )
```

## 参数
<a name="JSON_EXTRACT_ARRAY_ELEMENT_TEXT-arguments"></a>

 *json\$1string*  
格式正确的 JSON 字符串。

*pos*  
一个 `INTEGER`，表示要返回的数组元素的索引（使用从零开始的数组索引）。

*null\$1if\$1invalid*  
（可选）一个 `BOOLEAN` 值，指定在输入 JSON 字符串无效时是否返回 `NULL`，而不返回错误。要在 JSON 无效时返回 `NULL`，请指定 `true`（`t`）。要在 JSON 无效时返回错误，请指定 `false` (`f`)。默认为 `false`。

## 返回类型
<a name="JSON_EXTRACT_ARRAY_ELEMENT_TEXT-return"></a>

`VARCHAR`  
表示 *pos* 引用的 JSON 数组元素的 `VARCHAR` 字符串。

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

要返回位置 2 的数组元素（它是从零开始的数组索引的第三个元素），请使用以下示例：

```
SELECT JSON_EXTRACT_ARRAY_ELEMENT_TEXT('[111,112,113]', 2);
 
+---------------------------------+
| json_extract_array_element_text |
+---------------------------------+
|                             113 |
+---------------------------------+
```

要因为 JSON 无效而返回错误，请使用以下示例。

```
SELECT JSON_EXTRACT_ARRAY_ELEMENT_TEXT('["a",["b",1,["c",2,3,null,]]]',1);
 
ERROR: invalid json array object ["a",["b",1,["c",2,3,null,]]]
```

要将 *null\$1if\$1invalid* 设置为 *true*，以便语句返回 `NULL`，而不是在 JSON 无效时返回错误，请使用以下示例。

```
SELECT JSON_EXTRACT_ARRAY_ELEMENT_TEXT('["a",["b",1,["c",2,3,null,]]]',1,true);
 
+---------------------------------+
| json_extract_array_element_text |
+---------------------------------+
| NULL                            |
+---------------------------------+
```

考虑以下示例语句。如果提供的 JSON 字符串或索引为 NULL，则 JSON\$1EXTRACT\$1ARRAY\$1ELEMENT\$1TEXT 会返回 NULL，无论任何其他参数的值如何。

```
--Statement where json_string is NULL.
SELECT json_extract_array_element_text(NULL, 0)

 json_extract_array_element_text
---------------------------------
                            NULL

--Statement where pos is NULL and json_string is invalid JSON.
SELECT json_extract_array_element_text('invalid_json', NULL);

 json_extract_array_element_text
---------------------------------
                            NULL

--Statement where json_string is NULL and null_if_invalid is FALSE.
SELECT json_extract_array_element_text(NULL, 0, FALSE);

 json_extract_array_element_text
---------------------------------
                            NULL
```

考虑以下示例语句。如果 *null\$1if\$1invalid* 为 TRUE，则当 *json\$1string* 为无效 JSON 时，JSON\$1EXTRACT\$1ARRAY\$1ELEMENT\$1TEXT 会返回 NULL。如果 *null\$1if\$1invalid* 为 FALSE 或未设置，则当 *json\$1string* 无效时，该函数会返回错误。

```
--Statement with invalid JSON where null_if_invalid is TRUE.
SELECT json_extract_array_element_text('invalid_json', 0, TRUE);

 json_extract_array_element_text
---------------------------------
                            NULL
                            
--Statement with invalid JSON where null_if_invalid is FALSE.
SELECT json_extract_array_element_text('invalid_json', 0);

ERROR:  JSON parsing error
```

考虑以下示例，其中 *json\$1string* 是有效的 JSON，*pos* 指的是 JSON `null` 值。在此情况下，不管 *null\$1if\$1invalid* 的值如何，JSON\$1EXTRACT\$1ARRAY\$1ELEMENT\$1TEXT 都会返回 NULL。

```
--Statement selecting a null value.
SELECT json_extract_array_element_text('[null]', 0);

  json_extract_array_element_text 
----------------------------------
                             NULL
```

# JSON\$1EXTRACT\$1PATH\$1TEXT 函数
<a name="JSON_EXTRACT_PATH_TEXT"></a>

**注意**  
JSON\$1PARSE 及其关联函数将 JSON 值解析为 SUPER，Amazon Redshift 解析 SUPER 的效率比 VARCHAR 更高。  
我们建议您使用 [JSON\$1PARSE 函数](JSON_PARSE.md)解析 JSON 字符串来获取 SUPER 值，而不是使用 JSON\$1EXTRACT\$1PATH\$1TEXT。然后，使用 `value.attribute` 语法查询您想要的元素。有关在 SUPER 值中查询数组元素的更多信息，请转到[查询半结构化数据](query-super.md)。

JSON\$1EXTRACT\$1PATH\$1TEXT 函数返回 JSON 字符串中的一系列路径元素引用的键/值对的值。JSON 路径最深可嵌套至 5 层。路径元素区分大小写。如果 JSON 字符串中不存在路径元素，JSON\$1EXTRACT\$1PATH\$1TEXT 将返回 `NULL`。

如果 *null\$1if\$1invalid* 参数设置为 `TRUE` 并且 JSON 字符串无效，函数将返回 `NULL` 而不是返回错误。

JSON\$1EXTRACT\$1PATH\$1TEXT 的最大数据大小为 64 KB。因此，如果任何 JSON 记录大于 64KB，那么使用 JSON\$1EXTRACT\$1PATH\$1TEXT 处理记录会导致错误。

有关其他 JSON 函数的信息，请参阅 [JSON 函数](json-functions.md)。有关使用 JSON 的更多信息，请参阅[从 JSON 格式数据执行的 COPY 操作](copy-usage_notes-copy-from-json.md)。

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

```
JSON_EXTRACT_PATH_TEXT('json_string', 'path_elem' [,'path_elem'[, …] ] [, null_if_invalid ] )
```

## 参数
<a name="JSON_EXTRACT_PATH_TEXT-arguments"></a>

 *json\$1string*  
格式正确的 JSON 字符串。

*path\$1elem*  
JSON 字符串中的路径元素。需要一个路径元素。可指定额外的路径元素，最深五层。

*null\$1if\$1invalid*  
（可选）一个 `BOOLEAN` 值，指定在输入 JSON 字符串无效时是否返回 `NULL`，而不返回错误。要在 JSON 无效时返回 `NULL`，请指定 `TRUE`（`t`）。要在 JSON 无效时返回错误，请指定 `FALSE` (`f`)。默认为 `FALSE`。

在 JSON 字符串中，Amazon Redshift 将 `\n` 识别为换行符，将 `\t` 识别为制表符。要加载反斜杠，请使用反斜杠 ( `\\` ) 对其进行转义。有关更多信息，请参阅 [在 JSON 中转义字符](copy-usage_notes-copy-from-json.md#copy-usage-json-escape-characters)。

## 返回类型
<a name="JSON_EXTRACT_PATH_TEXT-return"></a>

`VARCHAR`  
表示路径元素引用的 JSON 值的 `VARCHAR` 字符串。

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

要返回路径 `'f4', 'f6'` 的值，请使用以下示例。

```
SELECT JSON_EXTRACT_PATH_TEXT('{"f2":{"f3":1},"f4":{"f5":99,"f6":"star"}}','f4', 'f6');

+------------------------+
| json_extract_path_text |
+------------------------+
| star                   |
+------------------------+
```

要因为 JSON 无效而返回错误，请使用以下示例。

```
SELECT JSON_EXTRACT_PATH_TEXT('{"f2":{"f3":1},"f4":{"f5":99,"f6":"star"}','f4', 'f6');

ERROR: invalid json object {"f2":{"f3":1},"f4":{"f5":99,"f6":"star"}
```

要将 *null\$1if\$1invalid* 设置为 *TRUE*，以便语句在 JSON 无效返回 `NULL`，而不是返回错误，请使用以下示例。

```
SELECT JSON_EXTRACT_PATH_TEXT('{"f2":{"f3":1},"f4":{"f5":99,"f6":"star"}','f4', 'f6',true);

+------------------------+
| json_extract_path_text |
+------------------------+
| NULL                   |
+------------------------+
```

在以下示例中，选择路径 `'farm', 'barn', 'color'` 的值，并且检索到的值位于第三级。为更便于阅读，此示例使用 JSON lint 工具进行格式化。

```
SELECT JSON_EXTRACT_PATH_TEXT('{
    "farm": {
        "barn": {
            "color": "red",
            "feed stocked": true
        }
    }
}', 'farm', 'barn', 'color');
+------------------------+
| json_extract_path_text |
+------------------------+
| red                    |
+------------------------+
```

要因为缺少 `'color'` 元素而返回 `NULL`，请使用以下示例。此示例使用 JSON lint 工具进行格式化。

```
SELECT JSON_EXTRACT_PATH_TEXT('{
    "farm": {
        "barn": {}
    }
}', 'farm', 'barn', 'color');

+------------------------+
| json_extract_path_text |
+------------------------+
| NULL                   |
+------------------------+
```

如果 JSON 有效，则尝试提取缺失的元素将返回 `NULL`。

要返回路径 `'house', 'appliances', 'washing machine', 'brand'` 的值，请使用以下示例。

```
SELECT JSON_EXTRACT_PATH_TEXT('{
  "house": {
    "address": {
      "street": "123 Any St.",
      "city": "Any Town",
      "state": "FL",
      "zip": "32830"
    },
    "bathroom": {
      "color": "green",
      "shower": true
    },
    "appliances": {
      "washing machine": {
        "brand": "Any Brand",
        "color": "beige"
      },
      "dryer": {
        "brand": "Any Brand",
        "color": "white"
      }
    }
  }
}', 'house', 'appliances', 'washing machine', 'brand');  

+------------------------+
| json_extract_path_text |
+------------------------+
| Any Brand              |
+------------------------+
```

以下示例创建一个示例表并用 SUPER 值填充该表，然后在两行中均返回路径 `'f2'` 的值。

```
CREATE TABLE json_example(id INT, json_text SUPER);

INSERT INTO json_example VALUES
(1, JSON_PARSE('{"f2":{"f3":1},"f4":{"f5":99,"f6":"star"}}')),
(2, JSON_PARSE('{
    "farm": {
        "barn": {
            "color": "red",
            "feed stocked": true
        }
    }
}'));

SELECT * FROM json_example;
id          | json_text
------------+--------------------------------------------
1           | {"f2":{"f3":1},"f4":{"f5":99,"f6":"star"}}
2           | {"farm":{"barn":{"color":"red","feed stocked":true}}}
 

SELECT id, JSON_EXTRACT_PATH_TEXT(JSON_SERIALIZE(json_text), 'f2') FROM json_example;
         
id          | json_text
------------+--------------------------------------------
1           | {"f3":1}
2           |
```

考虑以下示例语句。提供的 *path\$1elem* 为 NULL，因此 JSON\$1EXTRACT\$1PATH\$1TEXT 会返回 NULL，无论任何其他参数的值如何。

```
--Statement where path_elem is NULL and json_string is valid JSON.
SELECT JSON_EXTRACT_PATH_TEXT('{"f2":{"f3":1},"f4":{"f5":99,"f6":"star"}}',NULL);

 json_extract_path_text
------------------------
                   NULL

--Statement where only one path_elem is NULL.
SELECT JSON_EXTRACT_PATH_TEXT('{"f2":{"f3":1},"f4":{"f5":99,"f6":"star"}}','f4',NULL);

 json_extract_path_text
------------------------
                   NULL
                   
--Statement where path_elem is NULL and json_string is invalid JSON.
SELECT json_extract_path_text('invalid_json', NULL);

 json_extract_path_text
------------------------
                   NULL

--Statement where path_elem is NULL and null_if_invalid is FALSE.
SELECT json_extract_path_text(NULL, 0, FALSE);

 json_extract_path_text
------------------------
                   NULL
```

考虑以下示例语句。如果 *null\$1if\$1invalid* 为 TRUE，则当 *json\$1string* 为无效 JSON 时，JSON\$1EXTRACT\$1PATH\$1TEXT 会返回 NULL。如果 *null\$1if\$1invalid* 为 FALSE 或未设置，则当 *json\$1string* 无效时，该函数会返回错误。

```
--Statement with invalid JSON where null_if_invalid is TRUE.
SELECT json_extract_path_text('invalid_json', 0, TRUE);

 json_extract_path_text
------------------------
                   NULL
                                                    
--Statement with invalid JSON where null_if_invalid is FALSE.
SELECT json_extract_path_text('invalid_json', 0, FALSE);

ERROR:  JSON parsing error
```

考虑以下示例，其中 *json\$1string* 是有效的 JSON，*path\$1elem* 指的是 JSON `null` 值。在此情况下，JSON\$1EXTRACT\$1PATH\$1TEXT 会返回 NULL。同样，当 *path\$1elem* 指的是不存在的值时，JSON\$1EXTRACT\$1PATH\$1TEXT 会返回 NULL，无论 *null\$1if\$1invalid* 的值如何。

```
--Statement selecting a null value.
SELECT json_extract_path_text('[null]', 0);

  json_extract_path_text  
-------------------------
                    NULL   
                             
--Statement selecting a non-existing value.               
SELECT json_extract_path_text('{}', 'a');
       
  json_extract_path_text  
-------------------------
                    NULL
```

# 机器学习函数。
<a name="ml-function"></a>

通过使用 Amazon Redshift 机器学习（ML），您可以使用 SQL 语句训练机器学习模型，并在 SQL 查询中调用它们以进行预测。Amazon Redshift 模型可解释性包括功能重要性值，可帮助您了解训练数据中的每个属性对预测结果的贡献程度。

接下来，您可以找到对于 Amazon Redshift 支持的 SQL 机器学习函数的描述。

**Topics**
+ [EXPLAIN\$1MODEL 函数](r_explain_model_function.md)

# EXPLAIN\$1MODEL 函数
<a name="r_explain_model_function"></a>

EXPLAIN\$1MODEL 函数返回一个 SUPER 数据类型，其中以 JSON 格式提供了模型可解释性报告。可解释性报告中包含有关所有模型功能的 Shapley 值的信息。

EXPLAIN\$1MODEL 函数目前仅支持 AUTO ON 或 AUTO OFF XGBoost 模型。

如果未提供可解释性报告，函数将返回显示模型进度的状态。这包括 `Waiting for training job to complete`、`Waiting for processing job to complete` 和 `Processing job failed`。

运行 CREATE MODEL 语句时，解释状态将变为 `Waiting for training job to complete`。当模型经过训练并发送解释请求后，解释状态变为 `Waiting for processing job to complete`。成功完成模型解释后，即可获得完整的可解释性报告。否则，状态将变为 `Processing job failed`。

运行 CREATE MODEL 语句时，可以使用可选的 `MAX_RUNTIME` 参数，以指定训练应花费的最大时间量。一旦模型创建时间达到该时间，Amazon Redshift 就会停止创建模型。如果您在创建自动驾驶模型时达到该时间限制，Amazon Redshift 将返回到该时间为止最好的模型。一旦模型训练完成，模型可解释性就变为可用，因此，如果 `MAX_RUNTIME` 设置为较短的时间，可解释性报告可能不可用。训练时间各不相同，具体取决于模型复杂度、数据大小和其他因素。

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

```
EXPLAIN_MODEL ('schema_name.model_name')
```

## 参数
<a name="r_explain_model_function-argument"></a>

 *schema\$1name*   
架构的名称。如果未指定 schema\$1name，则会选择当前架构。

 *model\$1name*   
模型的名称。schema 中的模型名称必须是唯一的。

## 返回类型
<a name="r_explain_model_function-return-type"></a>

EXPLAIN\$1MODEL 函数会返回 SUPER 数据类型，如下所示。

```
{"version":"1.0","explanations":{"kernel_shap":{"label0":{"global_shap_values":{"x0":0.05,"x1":0.10,"x2":0.30,"x3":0.15},"expected_value":0.50}}}}
```

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

以下示例返回了解释状态 `waiting for training job to complete`。

```
select explain_model('customer_churn_auto_model');
                 explain_model
--------------------------------------------------------
{"explanations":"waiting for training job to complete"}
(1 row)
```

成功完成模型解释后，即可获得完整的可解释性报告，如下所示。

```
select explain_model('customer_churn_auto_model');
                                       explain_model
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{"version":"1.0","explanations":{"kernel_shap":{"label0":{"global_shap_values":{"x0":0.05386043365892927,"x1":0.10801289723274592,"x2":0.23227865827017378,"x3":0.0676685133940455,"x4":0.0897097667672375,"x5":0.08502141653270926,"x6":0.07581993936077065,"x7":0.16462880604578135},"expected_value":0.8492974042892456}}}}
(1 row)
```

由于 EXPLAIN\$1MODEL 函数返回了 SUPER 数据类型，因此您可以查询可解释性报告。这样，您可以提取 `global_shap_values`、`expected_value`，或特定于功能的 Shapley 值。

以下示例提取了模型的 `global_shap_values`。

```
select json_table.report.explanations.kernel_shap.label0.global_shap_values from (select explain_model('customer_churn_auto_model') as report) as json_table;
                                                       global_shap_values
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{"state":0.10983770427197151,"account_length":0.1772441398408543,"area_code":0.08626823968639591,"phone":0.0736669595282712,"intl_plan":3.344907436910987,"vmail_plan":0.09646600597854467,"vmail_message":0.2064922655089351,"day_mins":2.015038015251777,"day_calls":0.13179511076780168,"day_charge":0.4941091720480879,"eve_mins":0.46081379198626105,"eve_calls":0.16913440417758477,"eve_charge":0.09651014369401761,"night_mins":0.44218153640050845,"night_calls":0.15311640089218997,"night_charge":0.13850366104495426,"intl_mins":0.7583662464883899,"intl_calls":0.47144468610485685,"intl_charge":0.10945894673611875,"cust_serv_calls":0.31822051038387733}
(1 row)
```

以下示例提取了功能 x0 的 `global_shap_values` 。

```
select json_table.report.explanations.kernel_shap.label0.global_shap_values.x0 from (select explain_model('customer_churn_auto_model') as report) as json_table;
          x0
------------------------
  0.05386043365892927
(1 row)
```

如果模型是在特定架构中创建的，且您有权访问所创建的模型，则可以查询模型解释，如下所示。

```
-- Check the current schema
SHOW search_path;
   search_path
------------------
  $user, public
(1 row)         
-- If you have the privilege to access the model explanation
-- in `test_schema`
SELECT explain_model('test_schema.test_model_name');
                       explain_model
---------------------------------------------------------
{"explanations":"waiting for training job to complete"}
(1 row)
```

# 数学函数
<a name="Math_functions"></a>

**Topics**
+ [数学运算符符号](r_OPERATOR_SYMBOLS.md)
+ [ABS 函数](r_ABS.md)
+ [ACOS 函数](r_ACOS.md)
+ [ASIN 函数](r_ASIN.md)
+ [ATAN 函数](r_ATAN.md)
+ [ATAN2 函数](r_ATAN2.md)
+ [CBRT 函数](r_CBRT.md)
+ [CEILING（或 CEIL）函数](r_CEILING_FLOOR.md)
+ [COS 函数](r_COS.md)
+ [COT 函数](r_COT.md)
+ [DEGREES 函数](r_DEGREES.md)
+ [DEXP 函数](r_DEXP.md)
+ [DLOG1 函数](r_DLOG1.md)
+ [DLOG10 函数](r_DLOG10.md)
+ [EXP 函数](r_EXP.md)
+ [FLOOR 函数](r_FLOOR.md)
+ [LN 函数](r_LN.md)
+ [LOG 函数](r_LOG.md)
+ [MOD 函数](r_MOD.md)
+ [PI 函数](r_PI.md)
+ [POWER 函数](r_POWER.md)
+ [RADIANS 函数](r_RADIANS.md)
+ [RANDOM 函数](r_RANDOM.md)
+ [ROUND 函数](r_ROUND.md)
+ [SIN 函数](r_SIN.md)
+ [SIGN 函数](r_SIGN.md)
+ [SQRT 函数](r_SQRT.md)
+ [TAN 函数](r_TAN.md)
+ [TRUNC 函数](r_TRUNC.md)

本部分描述 Amazon Redshift 中支持的数学运算符和函数。

# 数学运算符符号
<a name="r_OPERATOR_SYMBOLS"></a>

 下表列出了支持的数学运算符。

## 支持的运算符
<a name="r_OPERATOR_SYMBOLS-supported-operators"></a>

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_OPERATOR_SYMBOLS.html)

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

以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要为给定的交易计算支付的佣金加 2.00 美元手续费，请使用以下示例。

```
SELECT
    commission,
    (commission + 2.00) AS comm
FROM
    sales
WHERE
    salesid = 10000;

+------------+-------+
| commission | comm  |
+------------+-------+
|      28.05 | 30.05 |
+------------+-------+
```

要为给定的交易计算销售价格的 20%，请使用以下示例。

```
SELECT pricepaid, (pricepaid * .20) as twentypct 
FROM sales 
WHERE salesid=10000;

+-----------+-----------+
| pricepaid | twentypct |
+-----------+-----------+
|       187 |      37.4 |
+-----------+-----------+
```

要根据持续增长模式预测票的销售量，请使用以下示例。在此示例中，子查询将返回 2008 年销售的票数。在此后 10 年，该结果将以 5% 的连续增长率呈指数增长。

```
SELECT (SELECT SUM(qtysold) FROM sales, date
WHERE sales.dateid=date.dateid AND year=2008)^((5::float/100)*10) AS qty10years;

+------------------+
|    qty10years    |
+------------------+
| 587.664019657491 |
+------------------+
```

要查找日期 ID 大于或等于 2000 的销售的总支付价格和总佣金，请使用以下示例。然后将总支付价格减去总佣金。

```
SELECT SUM(pricepaid) AS sum_price, dateid,
SUM(commission) AS sum_comm, (SUM(pricepaid) - SUM(commission)) AS value
FROM sales 
WHERE dateid >= 2000
GROUP BY dateid 
ORDER BY dateid 
LIMIT 10;

+-----------+--------+----------+-----------+
| sum_price | dateid | sum_comm |   value   |
+-----------+--------+----------+-----------+
|    305885 |   2000 | 45882.75 | 260002.25 |
|    316037 |   2001 | 47405.55 | 268631.45 |
|    358571 |   2002 | 53785.65 | 304785.35 |
|    366033 |   2003 | 54904.95 | 311128.05 |
|    307592 |   2004 |  46138.8 |  261453.2 |
|    333484 |   2005 |  50022.6 |  283461.4 |
|    317670 |   2006 |  47650.5 |  270019.5 |
|    351031 |   2007 | 52654.65 | 298376.35 |
|    313359 |   2008 | 47003.85 | 266355.15 |
|    323675 |   2009 | 48551.25 | 275123.75 |
+-----------+--------+----------+-----------+
```

# ABS 函数
<a name="r_ABS"></a>

 ABS 用于计算数字的绝对值，该数字可以是文本或计算结果为数字的表达式。

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

```
ABS(number)
```

## 参数
<a name="r_ABS-arguments"></a>

 *number*   
数字或计算结果为数字的表达式。它可以是 `SMALLINT`、`INTEGER`、`BIGINT`、`DECIMAL`、`FLOAT4`、`FLOAT8` 或 `SUPER` 类型。

## 返回类型
<a name="r_ABS-return-type"></a>

ABS 返回与其参数相同的数据类型。

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

要计算 `-38` 的绝对值，请使用以下示例：

```
SELECT ABS(-38);

+-----+
| abs |
+-----+
|  38 |
+-----+
```

要计算 `(14-76)` 的绝对值，请使用以下示例：

```
SELECT ABS(14-76);

+-----+
| abs |
+-----+
|  62 |
+-----+
```

# ACOS 函数
<a name="r_ACOS"></a>

ACOS 是返回数字的反余弦的三角函数。返回值采用弧度形式且介于 `0` 和 `PI` 之间。

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

```
ACOS(number)
```

## 参数
<a name="r_ACOS-arguments"></a>

 *number*   
输入参数是 `DOUBLE PRECISION` 数。

## 返回类型
<a name="r_ACOS-return-type"></a>

`DOUBLE PRECISION`

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

要返回 `-1` 的反余弦，请使用以下示例。

```
SELECT ACOS(-1);

+-------------------+
|       acos        |
+-------------------+
| 3.141592653589793 |
+-------------------+
```

要将 `.5` 的反余弦转换为等效的度数，请使用以下示例。

```
SELECT (ACOS(.5) * 180/(SELECT PI())) AS degrees;

+-------------------+
|      degrees      |
+-------------------+
| 60.00000000000001 |
+-------------------+
```

# ASIN 函数
<a name="r_ASIN"></a>

ASIN 是返回数字的反正弦的三角函数。返回值采用弧度形式且介于 `PI/2` 和 `-PI/2` 之间。

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

```
ASIN(number)
```

## 参数
<a name="r_ASIN-argument"></a>

 *number*   
输入参数是 `DOUBLE PRECISION` 数。

## 返回类型
<a name="r_ASIN-return-type"></a>

`DOUBLE PRECISION`

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

要返回 `1` 的反正弦，请使用以下示例。

```
SELECT ASIN(1) AS halfpi;

+--------------------+
|       halfpi       |
+--------------------+
| 1.5707963267948966 |
+--------------------+
```

要将 `.5` 的反正弦转换为等效的度数，请使用以下示例。

```
SELECT (ASIN(.5) * 180/(SELECT PI())) AS degrees;

+--------------------+
|      degrees       |
+--------------------+
| 30.000000000000004 |
+--------------------+
```

# ATAN 函数
<a name="r_ATAN"></a>

ATAN 是返回数字的反正切的三角函数。返回值采用弧度形式且介于 `-PI` 和 `PI` 之间。

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

```
ATAN(number)
```

## 参数
<a name="r_ATAN-argument"></a>

 *number*   
输入参数是 `DOUBLE PRECISION` 数。

## 返回类型
<a name="r_ATAN-return-type"></a>

`DOUBLE PRECISION`

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

要返回 `1` 的反正切并将其乘以 4，请使用以下示例。

```
SELECT ATAN(1) * 4 AS pi;
            
+-------------------+
|        pi         |
+-------------------+
| 3.141592653589793 |
+-------------------+
```

要将 `1` 的反正切转换为等效的度数，请使用以下示例。

```
SELECT (ATAN(1) * 180/(SELECT PI())) AS degrees;

+---------+
| degrees |
+---------+
|      45 |
+---------+
```

# ATAN2 函数
<a name="r_ATAN2"></a>

ATAN2 是一个三角函数，它返回两个数值相除的结果的反正切。返回值采用弧度形式且介于 `PI/2` 和 `-PI/2` 之间。

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

```
ATAN2(number1, number2)
```

## 参数
<a name="r_ATAN2-arguments"></a>

 *number1*   
`DOUBLE PRECISION` 数值。

 *number2*   
`DOUBLE PRECISION` 数值。

## 返回类型
<a name="r_ATAN2-return-type"></a>

`DOUBLE PRECISION`

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

要返回 `2/2` 的反正切并将其乘以 4，请使用以下示例。

```
SELECT ATAN2(2,2) * 4 AS PI;

+-------------------+
|        pi         |
+-------------------+
| 3.141592653589793 |
+-------------------+
```

要将 `1/0`（计算结果为 0）的反正切转换为等效的度数，请使用以下示例。

```
SELECT (ATAN2(1,0) * 180/(SELECT PI())) AS degrees;

+---------+
| degrees |
+---------+
|      90 |
+---------+
```

# CBRT 函数
<a name="r_CBRT"></a>

 CBRT 函数是计算给定数值的立方根的数学函数。

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

```
CBRT(number)
```

## 参数
<a name="r_CBRT-argument"></a>

CBRT 以 `DOUBLE PRECISION` 数值作为参数：

## 返回类型
<a name="r_CBRT-return-type"></a>

`DOUBLE PRECISION` 

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

以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要计算为给定交易支付的佣金的立方根，请使用以下示例。

```
SELECT CBRT(commission) FROM sales WHERE salesid=10000;

+--------------------+
|        cbrt        |
+--------------------+
| 3.0383953904884344 |
+--------------------+
```

# CEILING（或 CEIL）函数
<a name="r_CEILING_FLOOR"></a>

CEILING 或 CEIL 函数用于将数字向上舍入到下一个整数。（[FLOOR 函数](r_FLOOR.md)将数字向下舍入到下一个整数） 

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

```
{CEIL | CEILING}(number)
```

## 参数
<a name="r_CEILING_FLOOR-arguments"></a>

 *number*   
数字或计算结果为数字的表达式。它可以是 `SMALLINT`、`INTEGER`、`BIGINT`、`DECIMAL`、`FLOAT4`、`FLOAT8` 或 `SUPER` 类型。

## 返回类型
<a name="r_CEILING_FLOOR-return-type"></a>

CEILING 和 CEIL 返回与其参数相同的数据类型。

当输入为 `SUPER` 类型时，输出将保留与输入相同的动态类型，而静态类型仍为 SUPER 类型。当 `SUPER` 的动态类型不是数值时，Amazon Redshift 将返回 null。

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

以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要计算为给定的销售交易支付的佣金的上限，请使用以下示例。

```
SELECT CEILING(commission) FROM sales
WHERE salesid=10000;

+---------+
| ceiling |
+---------+
|      29 |
+---------+
```

# COS 函数
<a name="r_COS"></a>

COS 是返回数字的余弦的三角函数。返回值采用弧度形式且介于 `-1` 和 `1` 之间（含）。

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

```
COS(double_precision)
```

## 参数
<a name="r_COS-argument"></a>

 *number*   
输入参数是 `DOUBLE PRECISION` 数。

## 返回类型
<a name="r_COS-return-type"></a>

COS 函数返回 `DOUBLE PRECISION` 数值。

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

要返回 `0` 的余弦，请使用以下示例。

```
SELECT COS(0);

+-----+
| cos |
+-----+
|   1 |
+-----+
```

要返回 `pi` 的余弦，请使用以下示例。

```
SELECT COS(PI());

+-----+
| cos |
+-----+
|  -1 |
+-----+
```

# COT 函数
<a name="r_COT"></a>

COT 是返回数字的余切的三角函数。输入参数必须为非零。

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

```
COT(number)
```

## 参数
<a name="r_COT-argument"></a>

 *number*   
输入参数是 `DOUBLE PRECISION` 数。

## 返回类型
<a name="r_COT-return-type"></a>

`DOUBLE PRECISION`

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

要返回 1 的余切，请使用以下示例。

```
SELECT COT(1);

+--------------------+
|        cot         |
+--------------------+
| 0.6420926159343306 |
+--------------------+
```

# DEGREES 函数
<a name="r_DEGREES"></a>

将用弧度表示的角度转换用度表示。

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

```
DEGREES(number)
```

## 参数
<a name="r_DEGREES-argument"></a>

 *number*   
输入参数是 `DOUBLE PRECISION` 数。

## 返回类型
<a name="r_DEGREES-return-type"></a>

`DOUBLE PRECISION`

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

要返回 0.5 弧度的等效度数，请使用以下示例。

```
SELECT DEGREES(.5);

+-------------------+
|      degrees      |
+-------------------+
| 28.64788975654116 |
+-------------------+
```

要将 PI 弧度转换为度数，请使用以下示例。

```
SELECT DEGREES(pi());

+---------+
| degrees |
+---------+
|     180 |
+---------+
```

# DEXP 函数
<a name="r_DEXP"></a>

DEXP 函数返回双精度数的采用科学表示法的指数值。DEXP 函数和 EXP 函数的唯一区别在于 DEXP 的参数必须为 `DOUBLE PRECISION`。

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

```
DEXP(number)
```

## 参数
<a name="r_DEXP-argument"></a>

 *number*   
输入参数是 `DOUBLE PRECISION` 数。

## 返回类型
<a name="r_DEXP-return-type"></a>

`DOUBLE PRECISION`

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

以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

使用 DEXP 函数根据持续增长模式预测票的销售量。在此示例中，子查询将返回 2008 年销售的票数。该结果将乘以 DEXP 函数的结果（指定了在接下来 10 年保持 7% 的持续增长率）。

```
SELECT (SELECT SUM(qtysold) 
FROM sales, date
WHERE sales.dateid=date.dateid
AND year=2008) * DEXP((7::FLOAT/100)*10) qty2010;

+-------------------+
|      qty2010      |
+-------------------+
| 695447.4837722216 |
+-------------------+
```

# DLOG1 函数
<a name="r_DLOG1"></a>

DLOG1 函数返回输入参数的自然对数。[LN 函数](r_LN.md)的同义词。

# DLOG10 函数
<a name="r_DLOG10"></a>

DLOG10 返回输入参数的以 10 为底的对数。

[LOG 函数](r_LOG.md)的同义词。

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

```
DLOG10(number)
```

## 参数
<a name="r_DLOG10-argument"></a>

 *number*   
输入参数是 `DOUBLE PRECISION` 数。

## 返回类型
<a name="r_DLOG10-return-type"></a>

`DOUBLE PRECISION`

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

要返回数值 100 的以 10 为底的对数，请使用以下示例。

```
SELECT DLOG10(100);

+--------+
| dlog10 |
+--------+
|      2 |
+--------+
```

# EXP 函数
<a name="r_EXP"></a>

EXP 函数实施数值表达式的指数函数，即以自然对数 `e` 为底数，对表达式求次方。EXP 函数是 [LN 函数](r_LN.md)的反函数。

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

```
EXP(expression)
```

## 参数
<a name="r_EXP-argument"></a>

 *expression*   
表达式必须为 `INTEGER`、`DECIMAL` 或 `DOUBLE PRECISION` 数据类型。

## 返回类型
<a name="r_EXP-return-type"></a>

`DOUBLE PRECISION`

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

以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

使用 EXP 函数根据持续增长模式预测票的销售量。在此示例中，子查询将返回 2008 年销售的票数。该结果将乘以 EXP 函数的结果（指定了在接下来 10 年保持 7% 的持续增长率）。

```
SELECT (SELECT SUM(qtysold) 
FROM sales, date
WHERE sales.dateid=date.dateid
AND year=2008) * EXP((7::FLOAT/100)*10) qty2018;

+-------------------+
|      qty2018      |
+-------------------+
| 695447.4837722216 |
+-------------------+
```

# FLOOR 函数
<a name="r_FLOOR"></a>

FLOOR 函数将数字向下舍入到下一个整数。

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

```
FLOOR(number)
```

## 参数
<a name="r_FLOOR-argument"></a>

 *number*   
数字或计算结果为数字的表达式。它可以是 `SMALLINT`、`INTEGER`、`BIGINT`、`DECIMAL`、`FLOAT4`、`FLOAT8` 或 `SUPER` 类型。

## 返回类型
<a name="r_FLOOR-return-type"></a>

FLOOR 返回与其参数相同的数据类型。

当输入为 `SUPER` 类型时，输出将保留与输入相同的动态类型，而静态类型仍保留 `SUPER` 类型。当 `SUPER` 的动态类型不是数值时，Amazon Redshift 将返回 `NULL`。

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

以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要显示在使用 FLOOR 函数之前和之后为给定的销售交易支付的佣金值，请使用以下示例。

```
SELECT commission 
FROM sales 
WHERE salesid=10000;

+------------+
| commission |
+------------+
|      28.05 |
+------------+

SELECT FLOOR(commission) 
FROM sales 
WHERE salesid=10000;

+-------+
| floor |
+-------+
|    28 |
+-------+
```

# LN 函数
<a name="r_LN"></a>

返回输入参数的自然对数。

[DLOG1 函数](r_DLOG1.md)的同义词。

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

```
LN(expression)
```

## 参数
<a name="r_LN-argument"></a>

 *expression*   
对其执行函数的目标列或表达式。  
如果表达式引用了 Amazon Redshift 用户创建的表或者引用了 Amazon Redshift STL 或 STV 系统表，此函数将对某些数据类型返回错误。
具有以下数据类型的表达式在引用了用户创建的表或系统表时将产生错误。具有这些数据类型的表达式专用于在领导节点上运行：  
+ `BOOLEAN` 
+ `CHAR` 
+ `DATE` 
+ `DECIMAL` 或 `NUMERIC` 
+ `TIMESTAMP` 
+ `VARCHAR` 
具有以下数据类型的表达式可在用户创建的表以及 STL 或 STV 系统表上成功运行：  
+ `BIGINT` 
+ `DOUBLE PRECISION` 
+ `INTEGER` 
+ `REAL` 
+ `SMALLINT` 

## 返回类型
<a name="r_LN-return-type"></a>

LN 函数返回与输入 *expression* 相同的类型。

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

要返回数值 2.718281828 的自然对数或以 `e` 为底的对数，请使用以下示例。

```
SELECT LN(2.718281828);

+--------------------+
|         ln         |
+--------------------+
| 0.9999999998311267 |
+--------------------+
```

请注意，结果约等于 1。

以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要返回 USERS 表 userid 列中的值的自然对数，请使用以下示例。

```
SELECT username, LN(userid) FROM users ORDER BY userid LIMIT 10;

+----------+--------------------+
| username |         ln         |
+----------+--------------------+
| JSG99FHE |                  0 |
| PGL08LJI | 0.6931471805599453 |
| IFT66TXU | 1.0986122886681098 |
| XDZ38RDD | 1.3862943611198906 |
| AEB55QTM | 1.6094379124341003 |
| NDQ15VBM |  1.791759469228055 |
| OWY35QYB | 1.9459101490553132 |
| AZG78YIP | 2.0794415416798357 |
| MSD36KVR | 2.1972245773362196 |
| WKW41AIW |  2.302585092994046 |
+----------+--------------------+
```

# LOG 函数
<a name="r_LOG"></a>

返回数值的对数。

如果您使用这个函数来计算以 10 为底的对数，则也可以使用 [DLOG10 函数](r_DLOG10.md)。

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

```
LOG([base, ]argument)
```

## 参数
<a name="r_LOG-argument"></a>

 *base*   
（可选）对数函数的底。此数值必须为正数且不能等于 `1`。如果省略此参数，Amazon Redshift 将计算 *argument* 的以 10 为底的对数。

 *argument*   
对数函数的参数。此数值必须为正数。如果 *argument* 值为 `1`，则函数返回 `0`。

## 返回类型
<a name="r_LOG-return-type"></a>

LOG 函数返回 `DOUBLE PRECISION` 数值。

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

要查找 100 的以 2 为底的对数，请使用以下示例。

```
SELECT LOG(2, 100);
+-------------------+
|        log        |
+-------------------+
| 6.643856189774725 |
+-------------------+
```

要查找 100 的以 10 为底的对数，请使用以下示例。请注意，如果您省略底参数，则 Amazon Redshift 假设底为 10。

```
SELECT LOG(100);
            
+-----+
| log |
+-----+
|   2 |
+-----+
```

# MOD 函数
<a name="r_MOD"></a>

返回两个数字的余数，也称为*取模* 运算。将第一个参数除以第二个参数来计算结果。

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

```
MOD(number1, number2)
```

## 参数
<a name="r_MOD-arguments"></a>

 *number1*   
第一个输入参数是 `INTEGER`、`SMALLINT`、`BIGINT` 或 `DECIMAL` 数值。如果任一参数是 `DECIMAL` 类型，则另一参数也必须是 `DECIMAL` 类型。如果任一参数是 `INTEGER`，则另一参数可以是 `INTEGER`、`SMALLINT` 或 `BIGINT`。两个参数也可以都是 `SMALLINT` 或 `BIGINT`，但如果一个参数是 `BIGINT`，则另一个参数不能是 `SMALLINT`。

 *number2*   
第二个参数是 `INTEGER`、`SMALLINT`、`BIGINT` 或 `DECIMAL` 数值。相同的数据类型规则与 *number1* 一样适用于 *number2*。

## 返回类型
<a name="r_MOD-return-type"></a>

如果两个参数属于相同的类型，MOD 函数的返回类型是与输入参数相同的数值类型。但是，如果任一输入参数是 `INTEGER`，返回类型也将是 `INTEGER`。有效的返回类型为 `DECIMAL`、`INT`、`SMALLINT` 和 `BIGINT`。

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

您可以使用 `%` 作为取模运算符。

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

要返回一个数值除以另一个数值后的余数，请使用以下示例。

```
SELECT MOD(10, 4);
               
+-----+
| mod |
+-----+
|   2 |
+-----+
```

要在使用 MOD 函数时返回 `DECIMAL` 结果，请使用以下示例。

```
SELECT MOD(10.5, 4);
               
+-----+
| mod |
+-----+
| 2.5 |
+-----+
```

要在运行 MOD 函数之前强制转换数值，请使用以下示例。有关更多信息，请参阅 [CAST 函数](r_CAST_function.md)。

```
SELECT MOD(CAST(16.4 AS INTEGER), 5);
               
+-----+
| mod |
+-----+
|   1 |
+-----+
```

要通过将第一个参数除以 2 来检查该参数是否为偶数，请使用以下示例。

```
SELECT mod(5,2) = 0 AS is_even;
               
+---------+
| is_even |
+---------+
| false   |
+---------+
```

要使用 *%* 作为取模运算符，请使用以下示例。

```
SELECT 11 % 4 as remainder;
               
 +-----------+
| remainder |
+-----------+
|         3 |
+-----------+
```

以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要返回 CATEGORY 表中奇数类别的信息，请使用以下示例。

```
SELECT catid, catname
FROM category
WHERE MOD(catid,2)=1
ORDER BY 1,2;

+-------+-----------+
| catid |  catname  |
+-------+-----------+
|     1 | MLB       |
|     3 | NFL       |
|     5 | MLS       |
|     7 | Plays     |
|     9 | Pop       |
|    11 | Classical |
+-------+-----------+
```

# PI 函数
<a name="r_PI"></a>

PI 函数返回 14 个小数位的 pi 值。

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

```
PI()
```

## 返回类型
<a name="r_PI-return-type"></a>

`DOUBLE PRECISION`

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

要返回 pi 的值，请使用以下示例。

```
SELECT PI();

+-------------------+
|        pi         |
+-------------------+
| 3.141592653589793 |
+-------------------+
```

# POWER 函数
<a name="r_POWER"></a>

 POWER 函数是让一个数值表达式自乘到另一个数值表达式的幂的指数函数。例如，2 的三次幂的计算公式为 `POWER(2,3)`，结果为 `8`。

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

```
{POW | POWER}(expression1, expression2)
```

## 参数
<a name="r_POWER-arguments"></a>

 *expression1*   
要自乘的数值表达式。必须是 `INTEGER`、`DECIMAL` 或 `FLOAT` 数据类型。

 *expression2*   
让 *expression1* 自乘到的幂。必须是 `INTEGER`、`DECIMAL` 或 `FLOAT` 数据类型。

## 返回类型
<a name="r_POWER-return-type"></a>

`DOUBLE PRECISION`

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

以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

在以下示例中，POWER 函数用于根据 2008 年销售的票的数量（子查询的结果）预测将来 10 年的票销售情况。在此示例中，增长率设置为每年 7%。

```
SELECT (SELECT SUM(qtysold) FROM sales, date
WHERE sales.dateid=date.dateid
AND year=2008) * POW((1+7::FLOAT/100),10) qty2010;

+-------------------+
|      qty2010      |
+-------------------+
| 679353.7540885945 |
+-------------------+
```

以下示例是上一个示例的变体，其增长率为每年 7%，但间隔设置为月（10 年中的 120 个月）。

```
SELECT (SELECT SUM(qtysold) FROM sales, date
WHERE sales.dateid=date.dateid
AND year=2008) * POW((1+7::FLOAT/100/12),120) qty2010;

+-----------------+
|     qty2010     |
+-----------------+
| 694034.54678046 |
+-----------------+
```

# RADIANS 函数
<a name="r_RADIANS"></a>

RADIANS 函数将用度表示的角度转换为用弧度表示。

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

```
RADIANS(number)
```

## 参数
<a name="r_RADIANS-argument"></a>

 *number*   
输入参数是 `DOUBLE PRECISION` 数。

## 返回类型
<a name="r_RADIANS-return-type"></a>

`DOUBLE PRECISION`

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

要返回 180 度的等效弧度，请使用以下示例。

```
SELECT RADIANS(180);

+-------------------+
|      radians      |
+-------------------+
| 3.141592653589793 |
+-------------------+
```

# RANDOM 函数
<a name="r_RANDOM"></a>

RANDOM 函数生成介于 0.0（含）和 1.0（不含）之间的随机值。

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

```
RANDOM()
```

## 返回类型
<a name="r_RANDOM-return-type"></a>

`DOUBLE PRECISION`

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

在使用 [SET](r_SET.md) 命令设置种子值后调用 RANDOM 以使 RANDOM 生成可预测序列中的数。

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

要计算 0 到 99 之间的随机值，请使用以下示例。如果随机数为 0 - 1，此查询将生成 0 - 100 的随机数。

```
SELECT CAST(RANDOM() * 100 AS INT);

+------+
| int4 |
+------+
|   59 |
+------+
```

此示例使用 [SET](r_SET.md) 命令设置一个 SEED 值，以使 RANDOM 生成可预测的数字序列。

要返回三个 RANDOM 整数而不设置 SEED 值，请使用以下示例。

```
SELECT CAST(RANDOM() * 100 AS INT);
+------+
| int4 |
+------+
|    6 |
+------+

SELECT CAST(RANDOM() * 100 AS INT);
+------+
| int4 |
+------+
|   68 |
+------+

SELECT CAST(RANDOM() * 100 AS INT);
+------+
| int4 |
+------+
|   56 |
+------+
```

要将 SEED 值设置为 `.25`，然后返回三个 RANDOM 数值，请使用以下示例。

```
SET SEED TO .25;
SELECT CAST(RANDOM() * 100 AS INT);
+------+
| int4 |
+------+
|   21 |
+------+

SELECT CAST(RANDOM() * 100 AS INT);
+------+
| int4 |
+------+
|   79 |
+------+

SELECT CAST(RANDOM() * 100 AS INT);
+------+
| int4 |
+------+
|   12 |
+------+
```

要将 SEED 值重置为 `.25`，并验证 RANDOM 是否返回与前三个调用相同的结果，请使用以下示例。

```
SET SEED TO .25;
SELECT CAST(RANDOM() * 100 AS INT);
+------+
| int4 |
+------+
|   21 |
+------+

SELECT CAST(RANDOM() * 100 AS INT);
+------+
| int4 |
+------+
|   79 |
+------+

SELECT CAST(RANDOM() * 100 AS INT);
+------+
| int4 |
+------+
|   12 |
+------+
```

以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要从 SALES 表中检索 10 个项目的统一随机样本，请使用以下示例。

```
SELECT * 
FROM sales
ORDER BY RANDOM()
LIMIT 10;

+---------+--------+----------+---------+---------+--------+---------+-----------+------------+---------------------+
| salesid | listid | sellerid | buyerid | eventid | dateid | qtysold | pricepaid | commission |      saletime       |
+---------+--------+----------+---------+---------+--------+---------+-----------+------------+---------------------+
|   45422 |  51114 |     5983 |   24482 |    4369 |   2118 |       1 |       195 |      29.25 | 2008-10-19 05:20:07 |
|   42481 |  47638 |     4573 |    6198 |    6479 |   1987 |       4 |      1140 |        171 | 2008-06-10 09:39:19 |
|   31494 |  34759 |    18895 |    4719 |    7753 |   2090 |       4 |      1024 |      153.6 | 2008-09-21 03:44:26 |
|  119388 | 136685 |    21815 |   41905 |    2071 |   1884 |       1 |       359 |      53.85 | 2008-02-27 10:43:10 |
|  166990 | 225037 |    18529 |    7628 |     746 |   2113 |       1 |      2009 |     301.35 | 2008-10-14 10:07:44 |
|   11146 |  12096 |    42685 |    6619 |    1876 |   2123 |       1 |        29 |       4.35 | 2008-10-24 06:23:54 |
|  148537 | 172056 |    15102 |   11787 |    6122 |   1923 |       2 |       480 |         72 | 2008-04-07 03:58:23 |
|   68945 |  78387 |     7359 |   18323 |    6636 |   1910 |       1 |       457 |      68.55 | 2008-03-25 08:31:03 |
|   52796 |  59576 |     9909 |   15102 |    7958 |   1951 |       1 |       479 |      71.85 | 2008-05-05 02:25:08 |
|   90684 | 103522 |    38052 |   21549 |    7384 |   2117 |       1 |       313 |      46.95 | 2008-10-18 05:43:11 |
+---------+--------+----------+---------+---------+--------+---------+-----------+------------+---------------------+
```

要检索 10 个项目的随机样本，但选择与其价格成比例的项目，请使用以下示例。例如，价格是另一个项目的两倍的项目在查询结果中出现的可能性是两倍。

```
SELECT * 
FROM sales
ORDER BY -LOG(RANDOM()) / pricepaid
LIMIT 10;

+---------+--------+----------+---------+---------+--------+---------+-----------+------------+---------------------+
| salesid | listid | sellerid | buyerid | eventid | dateid | qtysold | pricepaid | commission |      saletime       |
+---------+--------+----------+---------+---------+--------+---------+-----------+------------+---------------------+
|  158340 | 208208 |    17082 |   42018 |    1211 |   2160 |       4 |      6852 |     1027.8 | 2008-11-30 12:21:43 |
|   53250 |  60069 |    12644 |    7066 |    7942 |   1838 |       4 |      1528 |      229.2 | 2008-01-12 11:24:56 |
|   22929 |  24938 |    47314 |    6503 |     179 |   2000 |       3 |       741 |     111.15 | 2008-06-23 08:04:50 |
|  164980 | 221181 |     1949 |   19670 |    1471 |   1906 |       1 |      1330 |      199.5 | 2008-03-21 07:59:51 |
|  159641 | 211179 |    44897 |   16652 |    7458 |   2128 |       1 |      1019 |     152.85 | 2008-10-29 02:02:15 |
|   73143 |  83439 |     5716 |    5727 |    7314 |   1903 |       1 |       248 |       37.2 | 2008-03-18 11:07:42 |
|   84778 |  96749 |    46608 |   32980 |    3883 |   1999 |       2 |       958 |      143.7 | 2008-06-22 12:13:31 |
|  171096 | 232929 |    43683 |    8536 |    8353 |   1870 |       1 |       929 |     139.35 | 2008-02-13 01:36:36 |
|   74212 |  84697 |    39809 |   15569 |    5525 |   2105 |       2 |       896 |      134.4 | 2008-10-06 11:47:50 |
|  158011 | 207556 |    25399 |   16881 |     232 |   2088 |       2 |      2526 |      378.9 | 2008-09-19 06:00:26 |
+---------+--------+----------+---------+---------+--------+---------+-----------+------------+---------------------+
```

# ROUND 函数
<a name="r_ROUND"></a>

ROUND 函数将数字舍入到最近的整数或小数。

ROUND 函数可以选择性地以 `INTEGER` 形式包含另一个参数，以指示在任意方向舍入到的小数位数。当您不提供第二个参数时，函数会舍入到最接近的整数。指定第二个参数 *integer* 时，函数将舍入为最接近的数值，其中精度为 *integer* 个小数位。

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

```
ROUND(number [ , integer ] )
```

## 参数
<a name="r_ROUND-argument"></a>

 *number*   
数字或计算结果为数字的表达式。它可以是 `DECIMAL`、`FLOAT8` 或 `SUPER` 类型。Amazon Redshift 可以隐式转换其他数值数据类型。

*（整数*）  
（可选）一个 `INTEGER`，指示以任意方向四舍五入的小数位数。此参数不支持 `SUPER` 数据类型。

## 返回类型
<a name="r_ROUND-return-type"></a>

ROUND 返回与输入 *number* 相同的数值数据类型。

当输入为 `SUPER` 类型时，输出将保留与输入相同的动态类型，而静态类型仍保留 `SUPER` 类型。当 `SUPER` 的动态类型不是数值时，Amazon Redshift 将返回 `NULL`。

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

以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要将为给定交易支付的佣金舍入到最近的整数，请使用以下示例。

```
SELECT commission, ROUND(commission)
FROM sales WHERE salesid=10000;

+------------+-------+
| commission | round |
+------------+-------+
|      28.05 |    28 |
+------------+-------+
```

要将为给定交易支付的佣金舍入到第一个小数位，请使用以下示例。

```
SELECT commission, ROUND(commission, 1)
FROM sales WHERE salesid=10000;

+------------+-------+
| commission | round |
+------------+-------+
|      28.05 |  28.1 |
+------------+-------+
```

要以与上一个示例相反的方向扩展精度，请使用以下示例。

```
SELECT commission, ROUND(commission, -1)
FROM sales WHERE salesid=10000;

+------------+-------+
| commission | round |
+------------+-------+
|      28.05 |    30 |
+------------+-------+
```

# SIN 函数
<a name="r_SIN"></a>

SIN 是返回数字的正弦的三角函数。返回值介于 `-1` 与 `1` 之间。

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

```
SIN(number)
```

## 参数
<a name="r_SIN-argument"></a>

 *number*   
以弧度表示的 `DOUBLE PRECISION` 数值。

## 返回类型
<a name="r_SIN-return-type"></a>

`DOUBLE PRECISION` 

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

要返回 `-PI` 的正弦，请使用以下示例。

```
SELECT SIN(-PI());

+-------------------------+
|           sin           |
+-------------------------+
| -0.00000000000000012246 |
+-------------------------+
```

# SIGN 函数
<a name="r_SIGN"></a>

 SIGN 函数返回数字的符号（正或负）。如果参数为正，则 SIGN 函数的结果为 `1`；如果参数为负，则结果为 `-1`；或者，如果参数为 `0`，则结果为 `0`。

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

```
SIGN(number)
```

## 参数
<a name="r_SIGN-argument"></a>

 *number*   
数字或计算结果为数字的表达式。它可以是 `DECIMAL`、`FLOAT8`、或 `SUPER` 类型。Amazon Redshift 可根据隐式转换规则转换其他数据类型。

## 返回类型
<a name="r_SIGN-return-type"></a>

SIGN 返回与输入参数相同的数值数据类型。如果输入为 `DECIMAL`，则输出为 `DECIMAL(1,0)`。

当输入为 `SUPER` 类型时，输出将保留与输入相同的动态类型，而静态类型仍保留 `SUPER` 类型。当 `SUPER` 的动态类型不是数值时，Amazon Redshift 将返回 `NULL`。

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

以下示例显示，由于输入是 `DOUBLE PRECISION`，表 t2 中的列 `d` 将 `DOUBLE PRECISION` 作为其类型；而由于输入是 `NUMERIC`，表 t2 中的列 `n` 将 `NUMERIC(1,0)` 作为输出。

```
CREATE TABLE t1(d DOUBLE PRECISION, n NUMERIC(12, 2));
INSERT INTO t1 VALUES (4.25, 4.25), (-4.25, -4.25);
CREATE TABLE t2 AS SELECT SIGN(d) AS d, SIGN(n) AS n FROM t1;
SELECT table_name, column_name, data_type FROM SVV_REDSHIFT_COLUMNS WHERE table_name='t1' OR table_name='t2';
 
+------------+-------------+-----------------------+
| table_name | column_name |       data_type       |
+------------+-------------+-----------------------+
| t1         | d           | double precision      |
| t1         | n           | numeric(12,2)         |
| t2         | d           | double precision      |
| t2         | n           | numeric(1,0)          |
| t1         | col1        | character varying(20) |
+------------+-------------+-----------------------+
```

以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要从 SALES 表中确定为给定交易支付的佣金的符号，请使用以下示例。

```
SELECT commission, SIGN(commission)
FROM sales WHERE salesid=10000;

+------------+------+
| commission | sign |
+------------+------+
|      28.05 |    1 |
+------------+------+
```

# SQRT 函数
<a name="r_SQRT"></a>

 SQRT 函数返回 `NUMERIC` 值的平方根。平方根是一个乘以自身以得到给定值的数字。

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

```
SQRT(expression)
```

## 参数
<a name="r_SQRT-argument"></a>

 *expression*   
表达式必须具有 `INTEGER`、`DECIMAL` 或 `FLOAT` 数据类型，或隐式转换为这些数据类型的数据类型。*expression* 可以包含函数。

## 返回类型
<a name="r_SQRT-return-type"></a>

`DOUBLE PRECISION`

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

要返回 16 的平方根，请使用以下示例。

```
SELECT SQRT(16);
               
+------+
| sqrt |
+------+
|    4 |
+------+
```

要使用隐式类型转换返回字符串 `16` 的平方根，请使用以下示例。

```
SELECT SQRT('16');
               
+------+
| sqrt |
+------+
|    4 |
+------+
```

要在使用 ROUND 函数后返回 16.4 的平方根，请使用以下示例。

```
SELECT SQRT(ROUND(16.4));
               
+------+
| sqrt |
+------+
|    4 |
+------+
```

要返回给定圆面积时的半径长度，请使用以下示例。例如，当给定以平方英寸为单位的面积时，它以英寸为单位计算半径。示例中的面积为 20。

```
SELECT SQRT(20/PI()) AS radius;
               
+--------------------+
|      radius        |
+--------------------+
| 2.5231325220201604 |
+--------------------+
```

以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要返回 SALES 表中 COMMISSION 值的平方根，请使用以下示例。COMMISSION 列是 `DECIMAL` 列。此示例说明如何在具有更复杂条件逻辑的查询中使用该函数。

```
SELECT SQRT(commission)
FROM sales WHERE salesid < 10 ORDER BY salesid;

+--------------------+
|        sqrt        |
+--------------------+
| 10.449880382090505 |
| 3.3763886032268267 |
|  7.245688373094719 |
|  5.123475382979799 |
|  4.806245936279167 |
|  7.687652437513028 |
| 10.871982339941507 |
| 5.4359911699707535 |
|   9.41541289588513 |
+--------------------+
```

要返回同一组 COMMISSION 值的平方根的舍入值，请使用以下示例。

```
SELECT ROUND(SQRT(commission))
FROM sales WHERE salesid < 10 ORDER BY salesid;

+-------+
| round |
+-------+
|    10 |
|     3 |
|     7 |
|     5 |
|     5 |
|     8 |
|    11 |
|     5 |
|     9 |
+-------+
```

# TAN 函数
<a name="r_TAN"></a>

TAN 是返回数字的正切的三角函数。输入参数是一个数值（用弧度表示）。

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

```
TAN(number)
```

## 参数
<a name="r_TAN-argument"></a>

 *number*   
`DOUBLE PRECISION` 数值。

## 返回类型
<a name="r_TAN-return-type"></a>

`DOUBLE PRECISION`

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

要返回 0 的正切，请使用以下示例。

```
SELECT TAN(0);

+-----+
| tan |
+-----+
|   0 |
+-----+
```

# TRUNC 函数
<a name="r_TRUNC"></a>

TRUNC 函数将数字截断为前一个整数或小数。

TRUNC 函数可以选择性地以 `INTEGER` 形式包含另一个参数，以指示在任意方向舍入到的小数位数。当您不提供第二个参数时，函数会舍入到最接近的整数。指定第二个参数 *integer* 时，函数将舍入为最接近的数值，其中精度为 *integer* 个小数位。

 这个函数也可以截断 `TIMESTAMP` 并返回 `DATE`。有关更多信息，请参阅 [TRUNC 函数](r_TRUNC_date.md)。

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

```
TRUNC(number [ , integer ])
```

## 参数
<a name="r_TRUNC-arguments"></a>

 *number*   
数值或计算结果为数值的表达式。它可以是 `DECIMAL`、`FLOAT8` 或 `SUPER` 类型。Amazon Redshift 可根据隐式转换规则转换其他数据类型。

 *（整数*）  
（可选）一个 `INTEGER`，指示精度在任意方向的小数位数。如果未提供 *integer*，数值将作为整数截断；如果指定了 *integer*，数值将截断到指定的小数位。`SUPER` 数据类型不支持此功能。

## 返回类型
<a name="r_TRUNC-return-type"></a>

TRUNC 返回与输入 *number* 相同的数据类型。

当输入为 `SUPER` 类型时，输出将保留与输入相同的动态类型，而静态类型仍保留 `SUPER` 类型。当 `SUPER` 的动态类型不是数值时，Amazon Redshift 将返回 `NULL`。

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

以下某些示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要截断为给定的销售交易支付的佣金，请使用以下示例。

```
SELECT commission, TRUNC(commission)
FROM sales WHERE salesid=784;

+------------+-------+
| commission | trunc |
+------------+-------+
|     111.15 |   111 |
+------------+-------+
```

要将同一佣金值截断到第一个小数位，请使用以下示例。

```
SELECT commission, TRUNC(commission,1)
FROM sales WHERE salesid=784;

+------------+-------+
| commission | trunc |
+------------+-------+
|     111.15 | 111.1 |
+------------+-------+
```

要为第二个参数使用负值截断佣金，请使用以下示例。请注意，`111.15` 向下四舍五入为 `110`。

```
SELECT commission, TRUNC(commission,-1)
FROM sales WHERE salesid=784;

+------------+-------+
| commission | trunc |
+------------+-------+
|     111.15 |   110 |
+------------+-------+
```

# 对象函数
<a name="Object_Functions"></a>

以下是 SQL 对象函数，Amazon Redshift 支持这些函数以创建 SUPER 类型对象并对这些对象执行操作：

**Topics**
+ [GET\$1NUMBER\$1ATTRIBUTES 函数](get_number_attributes.md)
+ [LOWER\$1ATTRIBUTE\$1NAMES 函数](r_lower_attribute_names.md)
+ [OBJECT 函数](r_object_function.md)
+ [OBJECT\$1TRANSFORM 函数](r_object_transform_function.md)
+ [UPPER\$1ATTRIBUTE\$1NAMES 函数](r_upper_attribute_names.md)

# GET\$1NUMBER\$1ATTRIBUTES 函数
<a name="get_number_attributes"></a>

返回有关字典对象的根层存在多少个键值对的计数。

## 语法
<a name="get_number_attributes-syntax"></a>

```
GET_NUMBER_ATTRIBUTES( super_expression )
```

## 参数
<a name="get_number_attributes-arguments"></a>

 *super\$1expression*   
字典形式的 SUPER 表达式。

## 返回类型
<a name="get_number_attributes-return-type"></a>

GET\$1NUMBER\$1ATTRIBUTES 函数返回 INT 类型。

## 注意
<a name="get_number_attributes-note"></a>

此函数仅计算直接属性的数量，而不包括嵌套字典中的对。

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

以下示例显示 GET\$1NUMBER\$1ATTRIBUTES 函数。

```
SELECT GET_NUMBER_ATTRIBUTES(JSON_PARSE('{"a": 1, "b": 2, "c": 3}'));
 get_number_attributes
-----------------------
            3
(1 row)
```

GET\$1NUMBER\$1ATTRIBUTES 函数仅在字典的第一层起作用。

```
SELECT GET_NUMBER_ATTRIBUTES(JSON_PARSE('{"a": 1, "b": {"c": 3}}'));
 get_number_attributes
-----------------------
            2
(1 row)
```

# LOWER\$1ATTRIBUTE\$1NAMES 函数
<a name="r_lower_attribute_names"></a>

使用与 [LOWER 函数](r_LOWER.md)相同的大小写转换例程，将 SUPER 值中的所有适用属性名称转换为小写。LOWER\$1ATTRIBUTE\$1NAMES 支持 UTF-8 多字节字符，每个字符最多可以有 4 个字节。

 要将 SUPER 属性名称转换为大写，请使用 [UPPER\$1ATTRIBUTE\$1NAMES 函数](r_upper_attribute_names.md)。

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

```
LOWER_ATTRIBUTE_NAMES( super_expression )
```

## 参数
<a name="r_lower_attribute_names-arguments"></a>

*super\$1expression*  
SUPER 表达式。

## 返回类型
<a name="r_lower_attribute_names-return-type"></a>

`SUPER`

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

在 Amazon Redshift 中，列标识符传统上不区分大小写且转换为小写。如果您从区分大小写的数据格式（例如 JSON）中提取数据，则数据可能包含大小写混合的属性名称。

考虑以下示例。

```
CREATE TABLE t1 (s) AS SELECT JSON_PARSE('{"AttributeName": "Value"}');


SELECT s.AttributeName FROM t1;  

attributename
-------------
NULL


SELECT s."AttributeName" FROM t1;

attributename
-------------
NULL
```

Amazon Redshift 对这两个查询都返回 NULL。要查询 `AttributeName`，请使用 LOWER\$1ATTRIBUTE\$1NAMES 将数据的属性名称转换为小写。考虑以下示例。

```
CREATE TABLE t2 (s) AS SELECT LOWER_ATTRIBUTE_NAMES(s) FROM t1;


SELECT s.attributename FROM t2;

attributename
-------------
"Value"


SELECT s.AttributeName FROM t2; 

attributename
-------------
"Value"


SELECT s."attributename" FROM t2;

attributename
-------------
"Value"


SELECT s."AttributeName" FROM t2;

attributename
-------------
"Value"
```

用于处理大小写混合的对象属性名称的一个相关选项是 `enable_case_sensitive_super_attribute` 配置选项，它让 Amazon Redshift 可以识别 SUPER 属性名称中的大小写。这可能是使用 LOWER\$1ATTRIBUTE\$1NAMES 的替代解决方案。有关 `enable_case_sensitive_super_attribute` 的更多信息，请转至 [enable\$1case\$1sensitive\$1super\$1attribute](r_enable_case_sensitive_super_attribute.md)。

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

**将 SUPER 属性名称转换为小写**  
以下示例使用 LOWER\$1ATTRIBUTE\$1NAMES 来转换表中所有 SUPER 值的属性名称。

```
-- Create a table and insert several SUPER values.
CREATE TABLE t (i INT, s SUPER);

INSERT INTO t VALUES
  (1, NULL), 
  (2, 'A'::SUPER),
  (3, JSON_PARSE('{"AttributeName": "B"}')),
  (4, JSON_PARSE(
     '[{"Subobject": {"C": "C"},
        "Subarray": [{"D": "D"}, "E"]
      }]'));

-- Convert all attribute names to lowercase.
UPDATE t SET s = LOWER_ATTRIBUTE_NAMES(s);

SELECT i, s FROM t ORDER BY i;

 i |                        s
---+--------------------------------------------------
 1 | NULL
 2 | "A"
 3 | {"attributename":"B"}
 4 | [{"subobject":{"c":"C"},"subarray":[{"d":"D"}, "E"]}]
```

观察 LOWER\$1ATTRIBUTE\$1NAMES 的工作原理。
+  NULL 值和标量 SUPER 值（例如 `"A"`）保持不变。
+  在 SUPER 对象中，所有属性名称都更改为小写，但诸如 `"B"` 之类的属性值保持不变。
+  LOWER\$1ATTRIBUTE\$1NAMES 以递归方式应用于嵌套在 SUPER 数组或其它对象内的任何 SUPER 对象。

**在具有重复属性名称的 SUPER 对象上使用 LOWER\$1ATTRIBUTE\$1NAMES**  
如果 SUPER 对象包含的属性的名称仅在大小写上有所不同，则 LOWER\$1ATTRIBUTE\$1NAMES 将引发错误。考虑以下示例。

```
SELECT LOWER_ATTRIBUTE_NAMES(JSON_PARSE('{"A": "A", "a": "a"}'));      

error:   Invalid input
code:    8001
context: SUPER value has duplicate attributes after case conversion.
```

# OBJECT 函数
<a name="r_object_function"></a>

创建 SUPER 数据类型的对象。

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

```
OBJECT ( [ key1, value1 ], [ key2, value2 ...] )
```

## 参数
<a name="r_object_function-arguments"></a>

*key1, key2*  
计算结果为 VARCHAR 类型字符串的表达式。

*value1, value2*  
除日期时间类型以外的任何 Amazon Redshift 数据类型的表达式，因为 Amazon Redshift 不会将日期时间类型强制转换为 SUPER 数据类型。有关日期时间类型的更多信息，请参阅[日期时间类型](r_Datetime_types.md)。  
对象中的 `value` 表达式无需为同一数据类型。

## 返回类型
<a name="r_object_function-returns"></a>

`SUPER`

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

```
-- Creates an empty object.
select object();

object
--------
{}
(1 row)
            
-- Creates objects with different keys and values.
select object('a', 1, 'b', true, 'c', 3.14);

object
---------------------------
{"a":1,"b":true,"c":3.14}
(1 row)
               
select object('a', object('aa', 1), 'b', array(2,3), 'c', json_parse('{}'));
               
object
---------------------------------
{"a":{"aa":1},"b":[2,3],"c":{}}
(1 row)
            
-- Creates objects using columns from a table.
create table bar (k varchar, v super);
insert into bar values ('k1', json_parse('[1]')), ('k2', json_parse('{}'));
select object(k, v) from bar;

object
------------
{"k1":[1]}
{"k2":{}}
(2 rows)
            
-- Errors out because DATE type values can't be converted to SUPER type.
select object('k', '2008-12-31'::date);

ERROR:  OBJECT could not convert type date to super
```

# OBJECT\$1TRANSFORM 函数
<a name="r_object_transform_function"></a>

转换 SUPER 对象。

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

```
OBJECT_TRANSFORM(
  input
  [KEEP path1, ...]
  [SET
    path1, value1,
    ...,  ...
  ]
)
```

## 参数
<a name="r_object_transform_function-arguments"></a>

* 输入*：  
解析为 SUPER 类型对象的表达式。

*KEEP*  
此子句中指定的所有*路径*值都将保留并传递到输出对象。  
此子句是可选的。

*path1*、*path2*...  
常量字符串文本，格式为双引号路径组成部分，以句点分隔。例如，`'"a"."b"."c"'` 是一个有效的路径值。这适用于 KEEP 和 SET 子句中的路径参数。

*SET*  
*路径*和*值*对，可修改现有路径或添加新路径，并在输出对象中设置该路径的值。  
此子句是可选的。

*value1*、*value2*...  
解析为 SUPER 类型值的表达式。请注意，数值、文本和布尔类型可解析为 SUPER。

## 返回类型
<a name="r_object_transform_function-returns"></a>

`SUPER`

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

OBJECT\$1TRANSFORM 返回一个 SUPER 类型对象，其中包含在 KEEP 中指定的*输入*路径值以及在 SET 中指定的*路径*和*值*对。

如果 KEEP 和 SET 都为空，则 OBJECT\$1TRANSFORM 返回*输入*。

如果*输入*不是 SUPER 类型*对象*，则无论 KEEP 或 SET 值如何，OBJECT\$1TRANSFORM 都会返回*输入*。

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

以下示例将一个 SUPER 对象转换为另一个 SUPER 对象。

```
CREATE TABLE employees (
    col_person SUPER
);

INSERT INTO employees
VALUES
    (
        json_parse('
            {
                "name": {
                    "first": "John",
                    "last": "Doe"
                },
                "age": 25,
                "ssn": "111-22-3333",
                "company": "Company Inc.",
                "country": "U.S."
            }
        ')
    ),
    (
        json_parse('
            {
                "name": {
                    "first": "Jane",
                    "last": "Appleseed"
                },
                "age": 34,
                "ssn": "444-55-7777",
                "company": "Organization Org.",
                "country": "Ukraine"
            }
        ')
    )
;

SELECT
    OBJECT_TRANSFORM(
        col_person
        KEEP
            '"name"."first"',
            '"age"',
            '"company"',
            '"country"'
        SET
            '"name"."first"', UPPER(col_person.name.first::TEXT),
            '"age"', col_person.age + 5,
            '"company"', 'Amazon'
    ) AS col_person_transformed
FROM employees;
    
--This result is formatted for ease of reading.
                  col_person_transformed
-------------------------------------------------------------
{
    "name": {
        "first": "JOHN"
    },
    "age": 30,
    "company": "Amazon",
    "country": "U.S."
}
{
    "name": {
        "first": "JANE"
    },
    "age": 39,
    "company": "Amazon",
    "country": "Ukraine"
}
```

# UPPER\$1ATTRIBUTE\$1NAMES 函数
<a name="r_upper_attribute_names"></a>

使用与 [UPPER 函数](r_UPPER.md)相同的大小写转换例程，将 SUPER 值中的所有适用属性名称转换为大写。UPPER\$1ATTRIBUTE\$1NAMES 支持 UTF-8 多字节字符，每个字符最多可以有 4 个字节。

 要将 SUPER 属性名称转换为小写，请使用 [LOWER\$1ATTRIBUTE\$1NAMES 函数](r_lower_attribute_names.md)。

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

```
UPPER_ATTRIBUTE_NAMES( super_expression )
```

## 参数
<a name="r_upper_attribute_names-arguments"></a>

*super\$1expression*  
SUPER 表达式。

## 返回类型
<a name="r_upper_attribute_names-return-type"></a>

`SUPER`

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

**将 SUPER 属性名称转换为大写**  
以下示例使用 UPPER\$1ATTRIBUTE\$1NAMES 来转换表中所有 SUPER 值的属性名称。

```
-- Create a table and insert several SUPER values.
CREATE TABLE t (i INT, s SUPER);

INSERT INTO t VALUES
  (1, NULL), 
  (2, 'a'::SUPER),
  (3, JSON_PARSE('{"AttributeName": "b"}')),
  (4, JSON_PARSE(
     '[{"Subobject": {"c": "c"},
        "Subarray": [{"d": "d"}, "e"]
      }]'));

-- Convert all attribute names to uppercase.
UPDATE t SET s = UPPER_ATTRIBUTE_NAMES(s);

SELECT i, s FROM t ORDER BY i;

 i |                        s
---+--------------------------------------------------
 1 | NULL
 2 | "a"
 3 | {"ATTRIBUTENAME":"B"}
 4 | [{"SUBOBJECT":{"C":"c"},"SUBARRAY":[{"D":"d"}, "e"]}]
```

观察 UPPER\$1ATTRIBUTE\$1NAMES 的工作原理。
+  NULL 值和标量 SUPER 值（例如 `"a"`）保持不变。
+  在 SUPER 对象中，所有属性名称都更改为大写，但诸如 `"b"` 之类的属性值保持不变。
+  UPPER\$1ATTRIBUTE\$1NAMES 以递归方式应用于嵌套在 SUPER 数组或其它对象内的任何 SUPER 对象。

**在具有重复属性名称的 SUPER 对象上使用 UPPER\$1ATTRIBUTE\$1NAMES**  
如果 SUPER 对象包含的属性的名称仅在大小写上有所不同，则 UPPER\$1ATTRIBUTE\$1NAMES 将引发错误。考虑以下示例。

```
SELECT UPPER_ATTRIBUTE_NAMES(JSON_PARSE('{"A": "A", "a": "a"}'));      

error:   Invalid input
code:    8001
context: SUPER value has duplicate attributes after case conversion.
```

# 空间函数
<a name="geospatial-functions"></a>

几何对象之间的关系基于维度扩展的九交模型 (DE-9IM)。此模型定义了诸如等于、包含和覆盖之类的谓词。有关空间关系的定义的更多信息，请参阅 Wikipedia 中的 [DE-9IM](https://en.wikipedia.org/wiki/DE-9IM)。

有关如何在 Amazon Redshift 中使用空间数据的更多信息，请参阅[在 Amazon Redshift 中查询空间数据](geospatial-overview.md)。

Amazon Redshift 提供了可以使用 `GEOMETRY` 和 `GEOGRAPHY` 数据类型的空间函数。下面列出了支持 `GEOGRAPHY` 数据类型的函数：
+ [ST\$1Area](ST_Area-function.md)
+ [ST\$1AsEWKT](ST_AsEWKT-function.md)
+ [ST\$1AsGeoJSON](ST_AsGeoJSON-function.md)
+ [ST\$1AsHexEWKB](ST_AsHexEWKB-function.md)
+ [ST\$1AsHexWKB](ST_AsHexWKB-function.md)
+ [ST\$1AsText](ST_AsText-function.md)
+ [ST\$1Distance](ST_Distance-function.md)
+ [ST\$1GeogFromText](ST_GeogFromText-function.md)
+ [ST\$1GeogFromWKB](ST_GeogFromWKB-function.md)
+ [ST\$1Length](ST_Length-function.md)
+ [ST\$1NPoints](ST_NPoints-function.md)
+ [ST\$1Perimeter](ST_Perimeter-function.md)

下面列出了 Amazon Redshift 支持的全套空间函数。

**Topics**
+ [AddBBox](AddBBox-function.md)
+ [DropBBox](DropBBox-function.md)
+ [GeometryType](GeometryType-function.md)
+ [H3\$1Boundary](H3_Boundary-function.md)
+ [H3\$1Center](H3_Center-function.md)
+ [H3\$1FromLongLat](H3_FromLongLat-function.md)
+ [H3\$1FromPoint](H3_FromPoint-function.md)
+ [H3\$1IsValid](H3_IsValid-function.md)
+ [H3\$1Polyfill](H3_Polyfill-function.md)
+ [H3\$1Resolution](H3_Resolution-function.md)
+ [H3\$1ToChildren](H3_ToChildren-function.md)
+ [H3\$1ToParent](H3_ToParent-function.md)
+ [ST\$1AddPoint](ST_AddPoint-function.md)
+ [ST\$1Angle](ST_Angle-function.md)
+ [ST\$1Area](ST_Area-function.md)
+ [ST\$1AsBinary](ST_AsBinary-function.md)
+ [ST\$1AsEWKB](ST_AsEWKB-function.md)
+ [ST\$1AsEWKT](ST_AsEWKT-function.md)
+ [ST\$1AsGeoJSON](ST_AsGeoJSON-function.md)
+ [ST\$1AsHexWKB](ST_AsHexWKB-function.md)
+ [ST\$1AsHexEWKB](ST_AsHexEWKB-function.md)
+ [ST\$1AsText](ST_AsText-function.md)
+ [ST\$1Azimuth](ST_Azimuth-function.md)
+ [ST\$1Boundary](ST_Boundary-function.md)
+ [ST\$1Buffer](ST_Buffer-function.md)
+ [ST\$1Centroid](ST_Centroid-function.md)
+ [ST\$1Collect](ST_Collect-function.md)
+ [ST\$1Contains](ST_Contains-function.md)
+ [ST\$1ContainsProperly](ST_ContainsProperly-function.md)
+ [ST\$1ConvexHull](ST_ConvexHull-function.md)
+ [ST\$1CoveredBy](ST_CoveredBy-function.md)
+ [ST\$1Covers](ST_Covers-function.md)
+ [ST\$1Crosses](ST_Crosses-function.md)
+ [ST\$1Dimension](ST_Dimension-function.md)
+ [ST\$1Disjoint](ST_Disjoint-function.md)
+ [ST\$1Distance](ST_Distance-function.md)
+ [ST\$1DistanceSphere](ST_DistanceSphere-function.md)
+ [ST\$1DWithin](ST_DWithin-function.md)
+ [ST\$1EndPoint](ST_EndPoint-function.md)
+ [ST\$1Envelope](ST_Envelope-function.md)
+ [ST\$1Equals](ST_Equals-function.md)
+ [ST\$1ExteriorRing](ST_ExteriorRing-function.md)
+ [ST\$1Force2D](ST_Force2D-function.md)
+ [ST\$1Force3D](ST_Force3D-function.md)
+ [ST\$1Force3DM](ST_Force3DM-function.md)
+ [ST\$1Force3DZ](ST_Force3DZ-function.md)
+ [ST\$1Force4D](ST_Force4D-function.md)
+ [ST\$1GeoHash](ST_GeoHash-function.md)
+ [ST\$1GeogFromText](ST_GeogFromText-function.md)
+ [ST\$1GeogFromWKB](ST_GeogFromWKB-function.md)
+ [ST\$1GeometryN](ST_GeometryN-function.md)
+ [ST\$1GeometryType](ST_GeometryType-function.md)
+ [ST\$1GeomFromEWKB](ST_GeomFromEWKB-function.md)
+ [ST\$1GeomFromEWKT](ST_GeomFromEWKT-function.md)
+ [ST\$1GeomFromGeoHash](ST_GeomFromGeoHash-function.md)
+ [ST\$1GeomFromGeoJSON](ST_GeomFromGeoJSON-function.md)
+ [ST\$1GeomFromGeoSquare](ST_GeomFromGeoSquare-function.md)
+ [ST\$1GeomFromText](ST_GeomFromText-function.md)
+ [ST\$1GeomFromWKB](ST_GeomFromWKB-function.md)
+ [ST\$1GeoSquare](ST_GeoSquare-function.md)
+ [ST\$1InteriorRingN](ST_InteriorRingN-function.md)
+ [ST\$1Intersects](ST_Intersects-function.md)
+ [ST\$1Intersection](ST_Intersection-function.md)
+ [ST\$1IsPolygonCCW](ST_IsPolygonCCW-function.md)
+ [ST\$1IsPolygonCW](ST_IsPolygonCW-function.md)
+ [ST\$1IsClosed](ST_IsClosed-function.md)
+ [ST\$1IsCollection](ST_IsCollection-function.md)
+ [ST\$1IsEmpty](ST_IsEmpty-function.md)
+ [ST\$1IsRing](ST_IsRing-function.md)
+ [ST\$1IsSimple](ST_IsSimple-function.md)
+ [ST\$1IsValid](ST_IsValid-function.md)
+ [ST\$1Length](ST_Length-function.md)
+ [ST\$1LengthSphere](ST_LengthSphere-function.md)
+ [ST\$1Length2D](ST_Length2D-function.md)
+ [ST\$1LineFromMultiPoint](ST_LineFromMultiPoint-function.md)
+ [ST\$1LineInterpolatePoint](ST_LineInterpolatePoint-function.md)
+ [ST\$1M](ST_M-function.md)
+ [ST\$1MakeEnvelope](ST_MakeEnvelope-function.md)
+ [ST\$1MakeLine](ST_MakeLine-function.md)
+ [ST\$1MakePoint](ST_MakePoint-function.md)
+ [ST\$1MakePolygon](ST_MakePolygon-function.md)
+ [ST\$1MemSize](ST_MemSize-function.md)
+ [ST\$1MMax](ST_MMax-function.md)
+ [ST\$1MMin](ST_MMin-function.md)
+ [ST\$1Multi](ST_Multi-function.md)
+ [ST\$1NDims](ST_NDims-function.md)
+ [ST\$1NPoints](ST_NPoints-function.md)
+ [ST\$1NRings](ST_NRings-function.md)
+ [ST\$1NumGeometries](ST_NumGeometries-function.md)
+ [ST\$1NumInteriorRings](ST_NumInteriorRings-function.md)
+ [ST\$1NumPoints](ST_NumPoints-function.md)
+ [ST\$1Perimeter](ST_Perimeter-function.md)
+ [ST\$1Perimeter2D](ST_Perimeter2D-function.md)
+ [ST\$1Point](ST_Point-function.md)
+ [ST\$1PointN](ST_PointN-function.md)
+ [ST\$1Points](ST_Points-function.md)
+ [ST\$1Polygon](ST_Polygon-function.md)
+ [ST\$1RemovePoint](ST_RemovePoint-function.md)
+ [ST\$1Reverse](ST_Reverse-function.md)
+ [ST\$1SetPoint](ST_SetPoint-function.md)
+ [ST\$1SetSRID](ST_SetSRID-function.md)
+ [ST\$1Simplify](ST_Simplify-function.md)
+ [ST\$1SRID](ST_SRID-function.md)
+ [ST\$1StartPoint](ST_StartPoint-function.md)
+ [ST\$1Touches](ST_Touches-function.md)
+ [ST\$1Transform](ST_Transform-function.md)
+ [ST\$1Union](ST_Union-function.md)
+ [ST\$1Within](ST_Within-function.md)
+ [ST\$1X](ST_X-function.md)
+ [ST\$1XMax](ST_XMax-function.md)
+ [ST\$1XMin](ST_XMin-function.md)
+ [ST\$1Y](ST_Y-function.md)
+ [ST\$1YMax](ST_YMax-function.md)
+ [ST\$1YMin](ST_YMin-function.md)
+ [ST\$1Z](ST_Z-function.md)
+ [ST\$1ZMax](ST_ZMax-function.md)
+ [ST\$1ZMin](ST_ZMin-function.md)
+ [SupportsBBox](SupportsBBox-function.md)

# AddBBox
<a name="AddBBox-function"></a>

AddBBox 返回支持使用预先计算的边界框进行编码的输入几何体的副本。有关对边界框的支持的更多信息，请参阅[边界框](spatial-terminology.md#spatial-terminology-bounding-box)。

## 语法
<a name="AddBBox-function-syntax"></a>

```
AddBBox(geom)
```

## 参数
<a name="AddBBox-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="AddBBox-function-return"></a>

`GEOMETRY`

如果 *geom* 为 null，则返回 null。

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

以下 SQL 返回支持使用边界框编码的输入多边形几何体的副本。

```
SELECT ST_AsText(AddBBox(ST_GeomFromText('POLYGON((0 0,1 0,0 1,0 0))')));
```

```
 st_astext
----------
 POLYGON((0 0,1 0,0 1,0 0))
```

# DropBBox
<a name="DropBBox-function"></a>

DropBBox 返回不支持使用预先计算的边界框进行编码的输入几何体的副本。有关对边界框的支持的更多信息，请参阅[边界框](spatial-terminology.md#spatial-terminology-bounding-box)。

## 语法
<a name="DropBBox-function-syntax"></a>

```
DropBBox(geom)
```

## 参数
<a name="DropBBox-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="DropBBox-function-return"></a>

`GEOMETRY`

如果 *geom* 为 null，则返回 null。

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

以下 SQL 返回不支持使用边界框编码的输入多边形几何体的副本。

```
SELECT ST_AsText(DropBBox(ST_GeomFromText('POLYGON((0 0,1 0,0 1,0 0))')));
```

```
 st_astext
----------
 POLYGON((0 0,1 0,0 1,0 0))
```

# GeometryType
<a name="GeometryType-function"></a>

GeometryType 以字符串形式返回输入几何体的子类型。

## 语法
<a name="GeometryType-function-syntax"></a>

```
GeometryType(geom)
```

## 参数
<a name="GeometryType-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="GeometryType-function-return"></a>

`VARCHAR`，表示 *geom* 的子类型。

如果 *geom* 为 null，则返回 null。

返回的值如下所示。


| 返回了 2D、3DZ、4D 几何体的字符串值 | 返回了 3DM 几何体的字符串值 | 几何体子类型 | 
| --- | --- | --- | 
| `POINT` | `POINTM` | 在 *geom* 为 `POINT` 子类型时返回  | 
| `LINESTRING` | `LINESTRINGM` | 在 *geom* 为 `LINESTRING` 子类型时返回  | 
| `POLYGON` | `POLYGONM` | 在 *geom* 为 `POLYGON` 子类型时返回  | 
| `MULTIPOINT` | `MULTIPOINTM` | 在 *geom* 为 `MULTIPOINT` 子类型时返回  | 
| `MULTILINESTRING` | `MULTILINESTRINGM` | 在 *geom* 为 `MULTILINESTRING` 子类型时返回  | 
| `MULTIPOLYGON` | `MULTIPOLYGONM` | 在 *geom* 为 `MULTIPOLYGON` 子类型时返回  | 
| `GEOMETRYCOLLECTION` | `GEOMETRYCOLLECTIONM` | 在 *geom* 为 `GEOMETRYCOLLECTION` 子类型时返回  | 

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

以下 SQL 转换多边形的已知文本 (WKT) 表示形式，并以字符串形式返回 `GEOMETRY` 子类型。

```
SELECT GeometryType(ST_GeomFromText('POLYGON((0 2,1 1,0 -1,0 2))'));
```

```
geometrytype
-------------
 POLYGON
```

# H3\$1Boundary
<a name="H3_Boundary-function"></a>

H3\$1Boundary 从输入索引返回 H3 单元格 ID 的边界。有关 H3 索引的信息，请参阅[H3](spatial-terminology.md#spatial-terminology-h3)。

## 语法
<a name="H3_Boundary-function-syntax"></a>

```
H3_Boundary(index)
```

## 参数
<a name="H3_Boundary-function-arguments"></a>

 * 索引*   
数据类型 `BIGINT` 或 `VARCHAR` 的一个值，表示 H3 单元格的索引。或一个表达式，其计算结果为其中一种数据类型。

## 返回类型
<a name="H3_Boundary-function-return"></a>

`POLYGON` – 表示空间参考系统标识符（SRID）为 `0` 的多边形。

如果 *index* 无效，则返回一个错误。

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

以下 SQL 输入表示 H3 单元格的索引的 `VARCHAR`，并返回 SRID 为 0 的 POLYGON，它表示输入 H3 单元格的边界。H3\$1Boundary 的输出将输入到 ST\$1AwEWKT，以扩展的已知文本（EWKT）表示形式显示。

```
SELECT ST_AsEWKT(H3_Boundary('8025fffffffffff'));
```

```
 st_asewkt
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 POLYGON((87.7729641223953 52.6542030078627,86.7082098104731 40.3127667561966,98.2285042557705 33.6210697806835,110.694610548823 37.163896485796,116.212895637138 47.3094513028131,106.40349563788 56.210610737585,87.7729641223953 52.6542030078627))
```

以下 SQL 输入表示 H3 单元格的索引的 `BIGINT`，并返回 SRID 为 0 的 POLYGON，它表示输入 H3 单元格的边界。H3\$1Boundary 的输出将输入到 ST\$1AwEWKT，以扩展的已知文本（EWKT）表示形式显示。

```
SELECT ST_AsEWKT(H3_Boundary(577129255373111295)); 
```

```
 st_asewkt
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
POLYGON((87.7729641223953 52.6542030078627,86.7082098104731 40.3127667561966,98.2285042557705 33.6210697806835,110.694610548823 37.163896485796,116.212895637138 47.3094513028131,106.40349563788 56.210610737585,87.7729641223953 52.6542030078627))
```

# H3\$1Center
<a name="H3_Center-function"></a>

H3\$1Center 从输入索引返回 H3 单元格 ID 的质心。有关 H3 索引的信息，请参阅[H3](spatial-terminology.md#spatial-terminology-h3)。

## 语法
<a name="H3_Center-function-syntax"></a>

```
H3_Center(index)
```

## 参数
<a name="H3_Center-function-arguments"></a>

 * 索引*   
数据类型 `BIGINT` 或 `VARCHAR` 的一个值，表示 H3 单元格的索引。或一个表达式，其计算结果为其中一种数据类型。

## 返回类型
<a name="H3_Center-function-return"></a>

`POINT` – 表示空间参考系统标识符（SRID）为 `0` 的 H3 单元格的质心。

如果 *index* 无效，则返回一个错误。

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

以下 SQL 输入表示 H3 单元格的索引的 `VARCHAR`，并返回 SRID 为 0 的 POINT，它表示输入 H3 单元格的质心。

```
SELECT H3_Center('8025fffffffffff');
```

```
 h3_center
--------------------------------------------
 010100000070707A550B605940AEE9D70B327E4640
```

以下 SQL 输入表示 H3 单元格的索引的 `BIGINT`，并返回 SRID 为 0 的 POINT，它表示输入 H3 单元格的质心。

```
SELECT H3_Center(577129255373111295);
```

```
 h3_center
--------------------------------------------
 010100000070707A550B605940AEE9D70B327E4640
```

以下 SQL 输入表示 H3 单元格的索引的 `VARCHAR`，并返回 SRID 为 0 的 POINT，它表示输入 H3 单元格的质心。H3\$1Center 的输出将输入到 ST\$1AwEWKT，以扩展的已知文本（EWKT）表示形式显示。

```
SELECT ST_AsEWKT(H3_Center('8075fffffffffff'));
```

```
 st_asewkt
-----------------------------------------
POINT(-5.24539029677733 2.30088211162675)
```

# H3\$1FromLongLat
<a name="H3_FromLongLat-function"></a>

H3\$1FromLongLat 根据输入的经度、纬度和分辨率返回相应的 H3 单元格 ID。有关 H3 索引的信息，请参阅[H3](spatial-terminology.md#spatial-terminology-h3)。

## 语法
<a name="H3_FromLongLat-function-syntax"></a>

```
H3_FromLongLat(longitude, latitude, resolution)
```

## 参数
<a name="H3_FromLongLat-function-arguments"></a>

 *经度*：、、  
一个 `DOUBLE PRECISION` 数据类型的值，或一个计算结果为 `DOUBLE PRECISION` 类型的表达式。

 *纬度*：、  
一个 `DOUBLE PRECISION` 数据类型的值，或一个计算结果为 `DOUBLE PRECISION` 类型的表达式。

 *resolution*   
一个 `INTEGER` 数据类型的值，或一个计算结果为 `INTEGER` 类型的表达式。该值表示 H3 网格系统的分辨率。该值必须是 0-15 之间的整数，包括 0 和 15。`0` 表示最粗糙，`15` 表示最精细。

## 返回类型
<a name="H3_FromLongLat-function-return"></a>

`BIGINT` – 表示 H3 单元格 ID。

如果 *resolution* 超出范围，则返回错误信息。

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

下面的 SQL 根据经度 `0`、纬度 `0` 和分辨率 `10` 返回 H3 单元格 ID。

```
SELECT H3_FromLongLat(0, 0, 10);
```

```
 h3_fromlonglat
-------------------
 623560421467684863
```

# H3\$1FromPoint
<a name="H3_FromPoint-function"></a>

H3\$1FromPoint 根据输入的几何点和分辨率返回相应的 H3 单元格 ID。有关 H3 索引的信息，请参阅[H3](spatial-terminology.md#spatial-terminology-h3)。

## 语法
<a name="H3_FromPoint-function-syntax"></a>

```
H3_FromPoint(geom, resolution)
```

## 参数
<a name="H3_FromPoint-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。*geom* 必须是 `POINT`。

 *resolution*   
一个 `INTEGER` 数据类型的值，或一个计算结果为 `INTEGER` 类型的表达式。该值表示 H3 网格系统的分辨率。该值必须是 0-15 之间的整数，包括 0 和 15。`0` 表示最粗糙，`15` 表示最精细。

## 返回类型
<a name="H3_FromPoint-function-return"></a>

`BIGINT` – 表示 H3 单元格 ID。

如果 *geom* 不是 `POINT`，则返回一个错误。

如果 *resolution* 超出范围，则返回错误信息。

如果 *geom* 为空，则返回 NULL。

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

下面的 SQL 根据点 `0,0` 和分辨率 `10` 返回 H3 单元格 ID。

```
SELECT H3_FromPoint(ST_GeomFromText('POINT(0 0)'), 10);
```

```
 h3_frompoint
-------------------
 623560421467684863
```

# H3\$1IsValid
<a name="H3_IsValid-function"></a>

如果输入表示 H3 单元格 ID，则 H3\$1IsValid 返回 true，否则返回 false。有关 H3 索引的信息，请参阅[H3](spatial-terminology.md#spatial-terminology-h3)。

## 语法
<a name="H3_IsValid-function-syntax"></a>

```
H3_IsValid(index)
```

## 参数
<a name="H3_IsValid-function-arguments"></a>

 * 索引*   
一个 `BIGINT` 或 `VARCHAR` 数据类型的值，或一个计算结果为这两种数据类型之一的表达式。

## 返回类型
<a name="H3_IsValid-function-return"></a>

`BOOLEAN`：如果输入表示有效的 H3 单元格 ID，则为 true，否则为 false。

如果 *index* 为 NULL，则返回 NULL。

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

以下 SQL 输入一个表示 H3 单元格 ID 的 VARCHAR，并返回 true。

```
SELECT H3_IsValid('8025fffffffffff');
```

```
 h3_isvalid
------------
 true
```

以下 SQL 输入一个表示 H3 单元格 ID 的 BIGINT，并返回 true。

```
SELECT H3_IsValid(577129255373111295);
```

```
 h3_isvalid
------------
 true
```

以下 SQL 输入一个无效的 H3 单元格 ID，并返回 false。

```
SELECT H3_IsValid('');
```

```
 h3_isvalid
------------
 false
```

# H3\$1Polyfill
<a name="H3_Polyfill-function"></a>

H3\$1Polyfill 返回与给定分辨率的输入多边形中所含六边形和五边形相对应的 H3 单元格 ID。有关 H3 索引的信息，请参阅[H3](spatial-terminology.md#spatial-terminology-h3)。

## 语法
<a name="H3_Polyfill-function-syntax"></a>

```
H3_Polyfill(geom, resolution)
```

## 参数
<a name="H3_Polyfill-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。*geom* 必须是 `POLYGON`。

 *resolution*   
一个 `INTEGER` 数据类型的值，或一个计算结果为 `INTEGER` 类型的表达式。该值表示 H3 网格系统的分辨率。该值必须是 0-15 之间的整数，包括 0 和 15。`0` 表示最粗糙，`15` 表示最精细。

## 返回类型
<a name="H3_Polyfill-function-return"></a>

`SUPER` – 表示 H3 单元格 ID 的列表。

如果 *geom* 不是 `POLYGON`，则返回一个错误。

如果 *resolution* 超出范围，则返回错误信息。

如果 *geom* 为空，则返回 NULL。

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

下面的 SQL 根据多边形和分辨率 `4` 返回一个 SUPER 数据类型数组，其中包含 H3 单元格 ID。

```
SELECT H3_Polyfill(ST_GeomFromText('POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))'), 4);
```

```
 h3_polyfill
----------------------------------------------------------------------------------------------------------------------------------------------------------
 [596538848238895103,596538805289222143,596538856828829695,596538813879156735,596537920525959167,596538685030137855,596538693620072447,596538839648960511]
```

# H3\$1Resolution
<a name="H3_Resolution-function"></a>

H3\$1Resolution 从输入索引返回 H3 单元格 ID 的分辨率。分辨率是一个介于 0（最粗略）和 15（最精细）之间的整数。有关 H3 索引的信息，请参阅[H3](spatial-terminology.md#spatial-terminology-h3)。

## 语法
<a name="H3_Resolution-function-syntax"></a>

```
H3_Resolution(index)
```

## 参数
<a name="H3_Resolution-function-arguments"></a>

 * 索引*   
一个 `BIGINT` 或 `VARCHAR` 数据类型的值，该值表示 H3 单元格的索引；或一个计算结果为这两种数据类型之一的表达式。

## 返回类型
<a name="H3_Resolution-function-return"></a>

`INTEGER`：表示输入 H3 单元格 ID 的分辨率。

如果 *index* 为 NULL，则返回 NULL。

如果 *index* 无效，则返回一个错误。

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

以下 SQL 输入一个表示 H3 单元格的索引的 VARCHAR，并返回一个表示输入 H3 单元格的分辨率的 INTEGER。

```
SELECT H3_Resolution('8025fffffffffff');
```

```
 h3_resolution
---------------
 0
```

以下 SQL 输入一个表示 H3 单元格的索引的 BIGINT，并返回一个表示输入 H3 单元格的分辨率的 INTEGER。

```
SELECT H3_Resolution(614553222213795839);
```

```
 h3_resolution
---------------
 8
```

# H3\$1ToChildren
<a name="H3_ToChildren-function"></a>

H3\$1ToChildren 返回给定 H3 索引在指定分辨率下的子 H3 单元格 ID 的列表。有关 H3 索引的信息，请参阅[H3](spatial-terminology.md#spatial-terminology-h3)。

## 语法
<a name="H3_ToChildren-function-syntax"></a>

```
H3_ToChildren(index, resolution)
```

## 参数
<a name="H3_ToChildren-function-arguments"></a>

 * 索引*   
一个 `BIGINT` 或 `VARCHAR` 数据类型的值，该值表示 H3 单元格的索引；或一个计算结果为这两种数据类型之一的表达式。

 *resolution*   
一个 `INTEGER` 数据类型的值，或一个计算结果为 `INTEGER` 类型的表达式。该值表示子单元格 ID 的分辨率。该值必须是介于输入 *index* 的分辨率和 15（含）之间的整数。

## 返回类型
<a name="H3_ToChildren-function-return"></a>

`SUPER` – 表示 H3 单元格 ID 的列表。

如果 *index* 或 *resolution* 为 NULL，则返回 NULL。

如果 *index* 无效，则返回一个错误。

如果 *resolution* 不在 *index* 的分辨率与 15（含）之间，则返回一个错误。

如果输出大小超过 SUPER 大小上限，则返回一个错误。

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

以下 SQL 输入一个表示 H3 单元格的索引的 VARCHAR 和一个表示所有子单元格的所需分辨率的 INTEGER，并返回一个 SUPER 数组，其中包含分辨率为 6 的子单元格。

```
SELECT H3_ToChildren('85283473fffffff', 6);
```

```
 h3_tochildren                                                
--------------------------------------------------------------------------------------------------------------------------------------
 [604189641121202175,604189641255419903,604189641389637631,604189641523855359,604189641658073087,604189641792290815,604189641926508543]
```

以下 SQL 输入一个表示 H3 单元格的索引的 BIGINT 和一个表示所有子单元格的所需分辨率的 INTEGER，并返回一个 SUPER 数组，其中包含分辨率为 6 的子单元格。

```
SELECT H3_ToChildren(599686042433355775, 6);
```

```
 h3_tochildren                                              
--------------------------------------------------------------------------------------------------------------------------------------
 [604189641121202175,604189641255419903,604189641389637631,604189641523855359,604189641658073087,604189641792290815,604189641926508543]
```

注意：*resolution* 和 *index* 分辨率之差不大于 7 是安全的。

以下示例演示针对超出 SUPER 大小限制的查询的解决方法。当输入 H3 索引和所需子单元格分辨率之间的分辨率之差太大（大于 7）时，此过程会以较小增量逐步展开子单元格（每次最多扩展 5 个分辨率层级），并将最终结果存储到用户创建的表中，由此解决该问题。

```
CREATE OR REPLACE PROCEDURE generate_h3_children()
LANGUAGE plpgsql
AS $$
BEGIN
    -- Drop and create h3_children table that will contain the results
    DROP TABLE IF EXISTS h3_children;
    CREATE TABLE h3_children (
        h3_index BIGINT,
        child_res INTEGER,
        children SUPER
    );

    -- Create temporary table for steps
    DROP TABLE IF EXISTS h3_steps;
    CREATE TABLE h3_steps (
        h3_index BIGINT,
        current_res INTEGER,
        target_res INTEGER,
        h3_array SUPER
    );

    -- Initial insert into h3_steps
    INSERT INTO h3_steps
    SELECT h3_index, H3_Resolution(h3_index), child_res, ARRAY(h3_index)
    FROM h3_indexes; -- Insert from your table with h3_index and child_res as columns

    -- Loop until we reach target resolution
    -- We expect at most 3 iterations considering that we can start at resolution
    -- 0 and target/child resolution equal to 15 (0 -> 5 -> 10 -> 15)
    WHILE EXISTS (
        SELECT 1
        FROM h3_steps h
        GROUP BY h3_index, target_res
        HAVING MAX(current_res) < target_res
    ) LOOP
        -- Populate the h3_steps table with the tables that need to
        -- reach closer to the target res
        INSERT INTO h3_steps
        SELECT
            h.h3_index,
            LEAST(h.current_res + 5, h.target_res), -- Do not exceed target res
            h.target_res,
            -- Take the children of the child cell at resolution current_res of the
            -- h3_index
            H3_ToChildren(c.child::BIGINT, LEAST(h.current_res + 5, h.target_res))
        FROM h3_steps h, UNNEST(h.h3_array) AS c(child)
        WHERE h.current_res < h.target_res
        AND h.current_res = (SELECT MAX(current_res)
                           FROM h3_steps
                           WHERE h3_index = h.h3_index
        );
    END LOOP;

    -- Store final results
    INSERT INTO h3_children
    SELECT h3_index AS h3_index, target_res AS child_res, h3_array AS children
    FROM h3_steps
    WHERE current_res = target_res;
END;
$$;

-- Create the source table for H3_ToChildren queries
CREATE TABLE h3_indexes (
    h3_index BIGINT,
    child_res INTEGER,
    PRIMARY KEY (h3_index, child_res)
);
INSERT INTO h3_indexes (h3_index, child_res)
VALUES (x'8001fffffffffff'::BIGINT, 11);

-- Execute the procedure
CALL generate_h3_children();

-- View results
SELECT * FROM h3_children;
```

# H3\$1ToParent
<a name="H3_ToParent-function"></a>

H3\$1ToParent 返回给定 H3 索引在指定父单元格分辨率下的父 H3 单元格 ID。有关 H3 索引的信息，请参阅[H3](spatial-terminology.md#spatial-terminology-h3)。

## 语法
<a name="H3_ToParent-function-syntax"></a>

```
H3_ToParent(index, resolution)
```

## 参数
<a name="H3_ToParent-function-arguments"></a>

 * 索引*   
一个 `BIGINT` 或 `VARCHAR` 数据类型的值，该值表示 H3 单元格的索引；或一个计算结果为这两种数据类型之一的表达式。

 *resolution*   
一个 `INTEGER` 数据类型的值，或一个计算结果为 `INTEGER` 类型的表达式。该值表示父单元格 ID 的分辨率。该值必须在 0 与 *index* 的分辨率（含）之间。

## 返回类型
<a name="H3_ToParent-function-return"></a>

`BIGINT`：表示父 H3 单元格 ID。

如果 *index* 或 *resolution* 为 NULL，则返回 NULL。

如果 *index* 无效，则返回一个错误。

如果 *resolution* 小于 0 或大于 *index* 的分辨率，则返回一个错误。

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

以下 SQL 输入一个表示 H3 单元格的索引的 VARCHAR 和一个表示所需父单元格的所需分辨率的 INTEGER，并返回一个表示输入 H3 单元格分辨率 0 下的父单元格的 BIGINT。

```
SELECT H3_ToParent('85283473fffffff', 0);
```

```
 h3_toparent
--------------------
 577199624117288959
```

以下 SQL 输入一个表示 H3 单元格的索引的 BIGINT 和一个表示所需父单元格的所需分辨率的 INTEGER，并返回一个表示输入 H3 单元格分辨率 0 下的父单元格的 BIGINT。

```
SELECT H3_ToParent(646078419604526808, 8);
```

```
 h3_toparent
--------------------
 614553222213795839
```

# ST\$1AddPoint
<a name="ST_AddPoint-function"></a>

ST\$1AddPoint 返回一个线串几何体，它与添加了点的输入几何体相同。如果提供了索引，则在索引位置添加点。如果索引为 -1 或未提供，则在线串后面附加点。

索引是从零开始的。结果的空间参考系统标识符 (SRID) 与输入几何体的相同。

返回的几何体的维度与 *geom1* 值的相同。如果 *geom1* 和 *geom2* 具有不同的维度，则 *geom2* 会投影到 *geom1* 的维度。

## 语法
<a name="ST_AddPoint-function-syntax"></a>

```
ST_AddPoint(geom1, geom2)
```

```
ST_AddPoint(geom1, geom2, index)
```

## 参数
<a name="ST_AddPoint-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `LINESTRING`。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `POINT`。该点可以是空点。

 *index*   
一个 `INTEGER` 数据类型的值，表示从零开始的索引的位置。

## 返回类型
<a name="ST_AddPoint-function-return"></a>

`GEOMETRY` 

如果 *geom1*、*geom2* 或 *index* 为 null，则返回 null。

如果 *geom2* 是空点，则会返回 *geom1* 的副本。

如果 *geom1* 不是 `LINESTRING`，则返回一个错误。

如果 *geom2* 不是 `POINT`，则返回一个错误。

如果 *index* 超出范围，则返回一个错误。索引位置的有效值为 -1 或为一个介于 0 和 `ST_NumPoints(geom1)` 之间的值。

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

以下 SQL 向线串添加点以使其成为闭合线串。

```
WITH tmp(g) AS (SELECT ST_GeomFromText('LINESTRING(0 0,10 0,10 10,5 5,0 5)',4326))
SELECT ST_AsEWKT(ST_AddPoint(g, ST_StartPoint(g))) FROM tmp;
```

```
 st_asewkt
------------------------------------------------
 SRID=4326;LINESTRING(0 0,10 0,10 10,5 5,0 5,0 0)
```

以下 SQL 将点添加到线串中的特定位置。

```
WITH tmp(g) AS (SELECT ST_GeomFromText('LINESTRING(0 0,10 0,10 10,5 5,0 5)',4326))
SELECT ST_AsEWKT(ST_AddPoint(g, ST_SetSRID(ST_Point(5, 10), 4326), 3)) FROM tmp;
```

```
 st_asewkt
------------------------------------------------
 SRID=4326;LINESTRING(0 0,10 0,10 10,5 10,5 5,0 5)
```

# ST\$1Angle
<a name="ST_Angle-function"></a>

ST\$1Angle 返回顺时针方向测量的点之间的角度（以弧度为单位），如下所示：
+ 如果输入三个点，则测量返回的角度 P1-P2-P3，就好像通过围绕 P2 顺时针从 P1 旋转到 P3 获得角度一样。
+ 如果输入四个点，则返回有向线段 P1-P2 和 P3-P4 形成的返回顺时针角度。如果输入为退化情况（即，P1 等于 P2，或 P3 等于 P4），则返回 null。

返回值以弧度为单位且在 [0, 2π) 范围内。

ST\$1Angle 对输入几何体的 2D 投影进行操作。

## 语法
<a name="ST_Angle-function-syntax"></a>

```
ST_Angle(geom1, geom2, geom3)
```

```
ST_Angle(geom1, geom2, geom3, geom4)
```

## 参数
<a name="ST_Angle-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `POINT`。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `POINT`。

 *geom3*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `POINT`。

 *geom4*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `POINT`。

## 返回类型
<a name="ST_Angle-function-return"></a>

`DOUBLE PRECISION`. 

如果 *geom1* 等于 *geom2*，或者 *geom2* 等于 *geom3*，则返回 null。

如果 *geom1*、*geom2*、*geom3* 或 *geom4* 为 null，则返回 null。

如果 *geom1*、*geom2*、*geom3* 或 *geom4* 中的任何一个为空点，则返回一个错误。

如果 *geom1*、*geom2*、*geom3* 和 *geom4* 不具有相同的空间参考系统标识符（SRID）值，则返回一个错误。

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

以下 SQL 返回转换为三个输入点度数的角度。

```
SELECT ST_Angle(ST_Point(1,1), ST_Point(0,0), ST_Point(1,0)) / Pi() * 180.0 AS angle;
```

```
 angle
---------------
    45
```

以下 SQL 返回转换为四个输入点度数的角度。

```
SELECT ST_Angle(ST_Point(1,1), ST_Point(0,0), ST_Point(1,0), ST_Point(2,0)) / Pi() * 180.0 AS angle;
```

```
 angle
---------------
   225
```

# ST\$1Area
<a name="ST_Area-function"></a>

对于输入几何体，ST\$1Area 返回 2D 投影的笛卡尔面积。面积单位与用于表示输入几何体坐标的单位相同。对于点、线串、多点和多线串，此函数返回 0。对于几何体集合，它返回集合中几何体的面积之和。

对于输入地理，ST\$1Area 返回由 SRID 确定的在椭球体上计算的输入平面地理的 2D 投影的测地线面积。长度以平方米为单位。对于点、多点和线性地理，此函数返回零 (0)。当输入为几何体集合时，此函数返回集合中的平面地理面积之和。

## 语法
<a name="ST_Area-function-syntax"></a>

```
ST_Area(geo)
```

## 参数
<a name="ST_Area-function-arguments"></a>

 *geo*   
一个 `GEOMETRY` 或 `GEOGRAPHY` 数据类型的值，或一个计算结果为 `GEOMETRY` 或 `GEOGRAPHY` 类型的表达式。

## 返回类型
<a name="ST_Area-function-return"></a>

`DOUBLE PRECISION`

如果 *geo* 为 null，则返回 null。

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

以下 SQL 返回多边形的笛卡尔面积。

```
SELECT ST_Area(ST_GeomFromText('MULTIPOLYGON(((0 0,10 0,0 10,0 0)),((10 0,20 0,20 10,10 0)))'));
```

```
 st_area
---------
     100
```

以下 SQL 返回地理中多边形的面积。

```
SELECT ST_Area(ST_GeogFromText('polygon((34 35, 28 30, 25 34, 34 35))'));
```

```
     st_area
------------------
 201824655743.383
```

以下 SQL 对线性地理返回零。

```
SELECT ST_Area(ST_GeogFromText('multipoint(0 0, 1 1, -21.32 121.2)'));
```

```
 st_area
---------
       0
```

# ST\$1AsBinary
<a name="ST_AsBinary-function"></a>

ST\$1AsBinary 返回输入几何体的十六进制已知二进制 (WKB) 表示形式。对于 3DZ、3DM 和 4D 几何体，ST\$1AsBinary 使用开放地理空间联盟 (OGC) 标准值作为几何体类型。

## 语法
<a name="ST_AsBinary-function-syntax"></a>

```
ST_AsBinary(geom)
```

## 参数
<a name="ST_AsBinary-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_AsBinary-function-return"></a>

`VARBYTE`

如果 *geom* 为 null，则返回 null。

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

以下 SQL 返回多边形的十六进制 WKB 表示形式。

```
SELECT ST_AsBinary(ST_GeomFromText('POLYGON((0 0,0 1,1 1,1 0,0 0))',4326));
```

```
st_asbinary
--------------------------------
01030000000100000005000000000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000000000000000000000000000000000000000
```

# ST\$1AsEWKB
<a name="ST_AsEWKB-function"></a>

ST\$1AsEWKB 返回输入几何体的扩展的已知二进制 (EWKB) 表示形式。对于 3DZ、3DM 和 4D 几何体，ST\$1AsEWKB 使用开放地理空间联盟 (OGC) 标准值作为几何体类型。

## 语法
<a name="ST_AsEWKB-function-syntax"></a>

```
ST_AsEWKB(geom)
```

## 参数
<a name="ST_AsEWKB-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_AsEWKB-function-return"></a>

`VARBYTE`

如果 *geom* 为 null，则返回 null。

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

以下 SQL 返回多边形的十六进制 EWKB 表示形式。

```
SELECT ST_AsEWKB(ST_GeomFromText('POLYGON((0 0,0 1,1 1,1 0,0 0))',4326));
```

```
st_asewkb
--------------------------------
0103000020E61000000100000005000000000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000000000000000000000000000000000000000
```

# ST\$1AsEWKT
<a name="ST_AsEWKT-function"></a>

ST\$1AsEWKT 返回输入几何体或地理的扩展的已知文本 (EWKT) 表示形式。对于 3DZ、3DM 和 4D 几何体，ST\$1AsEWKT 会将 Z、M 或 ZM 附加到几何类型的 WKT 值。

## 语法
<a name="ST_AsEWKT-function-syntax"></a>

```
ST_AsEWKT(geo)
```

```
ST_AsEWKT(geo, precision)
```

## 参数
<a name="ST_AsEWKT-function-arguments"></a>

 *geo*   
一个 `GEOMETRY` 或 `GEOGRAPHY` 数据类型的值，或一个计算结果为 `GEOMETRY` 或 `GEOGRAPHY` 类型的表达式。

 *精度*   
一个 数据类型的 值`INTEGER` 对于几何体，*geo* 的坐标使用指定的精度 1–20 显示。如果未指定*精度*，则默认值为 15。对于地理，*geo* 的坐标使用指定的精度显示。如果未指定*精度*，则默认值为 15。

## 返回类型
<a name="ST_AsEWKT-function-return"></a>

`VARCHAR`

如果 *geo* 为 null，则返回 null。

如果*精度* 为 null，则返回 null。

如果结果大于 64-KB `VARCHAR`，则将返回一个错误。

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

以下 SQL 返回线串的 EWKT 表示形式。

```
SELECT ST_AsEWKT(ST_GeomFromText('LINESTRING(3.141592653589793 -6.283185307179586,2.718281828459045 -1.414213562373095)', 4326));
```

```
st_asewkt
--------------------------------
 SRID=4326;LINESTRING(3.14159265358979 -6.28318530717959,2.71828182845905 -1.41421356237309)
```

以下 SQL 返回线串的 EWKT 表示形式。使用六位数精度显示几何体的坐标。

```
SELECT ST_AsEWKT(ST_GeomFromText('LINESTRING(3.141592653589793 -6.283185307179586,2.718281828459045 -1.414213562373095)', 4326), 6);
```

```
st_asewkt
--------------------------------
 SRID=4326;LINESTRING(3.14159 -6.28319,2.71828 -1.41421)
```

以下 SQL 返回地理的 EWKT 表示形式。

```
SELECT ST_AsEWKT(ST_GeogFromText('LINESTRING(110 40, 2 3, -10 80, -7 9)'));
```

```
                  st_asewkt
----------------------------------------------
 SRID=4326;LINESTRING(110 40,2 3,-10 80,-7 9)
```

# ST\$1AsGeoJSON
<a name="ST_AsGeoJSON-function"></a>

ST\$1AsGeoJSON 返回输入几何体或地理的 GeoJSON 表示形式。有关 GeoJSON 的更多信息，请参阅 Wikipedia 中的 [GeoJSON](https://en.wikipedia.org/wiki/GeoJSON)。

对于 3DZ 和 4D 几何体，输出几何体是输入 3DZ 或 4D 几何体的 3DZ 投影。也就是说，`x`、`y`, 和 `z` 坐标存在于输出中。对于 3DZ 几何体，输出几何体是输入 3DM 几何体的 2D 投影。也就是说，只有 `x` 和 `y` 坐标存在于输出中。

对于输入地理，ST\$1AsGeoJSON 返回输入地理的 GeoJSON 表示形式。地理的坐标使用指定的精度显示。

## 语法
<a name="ST_AsGeoJSON-function-syntax"></a>

```
ST_AsGeoJSON(geo)
```

```
ST_AsGeoJSON(geo, precision)
```

## 参数
<a name="ST_AsGeoJSON-function-arguments"></a>

 *geo*   
一个 `GEOMETRY` 或 `GEOGRAPHY` 数据类型的值，或一个计算结果为 `GEOMETRY` 或 `GEOGRAPHY` 类型的表达式。

 *精度*   
一个 数据类型的 值`INTEGER` 对于几何体，*geo* 的坐标使用指定的精度 1–20 显示。如果未指定*精度*，则默认值为 15。对于地理，*geo* 的坐标使用指定的精度显示。如果未指定*精度*，则默认值为 15。

## 返回类型
<a name="ST_AsGeoJSON-function-return"></a>

`VARCHAR`

如果 *geo* 为 null，则返回 null。

如果*精度* 为 null，则返回 null。

如果结果大于 64-KB `VARCHAR`，则将返回一个错误。

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

以下 SQL 返回线串的 GeoJSON 表示形式。

```
SELECT ST_AsGeoJSON(ST_GeomFromText('LINESTRING(3.141592653589793 -6.283185307179586,2.718281828459045 -1.414213562373095)'));
```

```
st_asgeojson
----------------------------------------------------------------------------------------------------------------
 {"type":"LineString","coordinates":[[3.14159265358979,-6.28318530717959],[2.71828182845905,-1.41421356237309]]}
```

以下 SQL 返回线串的 GeoJSON 表示形式。使用六位数精度显示几何体的坐标。

```
SELECT ST_AsGeoJSON(ST_GeomFromText('LINESTRING(3.141592653589793 -6.283185307179586,2.718281828459045 -1.414213562373095)'), 6);
```

```
st_asgeojson
-----------------------------------------------------------------------------
  {"type":"LineString","coordinates":[[3.14159,-6.28319],[2.71828,-1.41421]]}
```

以下 SQL 返回地理的 GeoJSON 表示形式。

```
SELECT ST_AsGeoJSON(ST_GeogFromText('LINESTRING(110 40, 2 3, -10 80, -7 9)'));
```

```
                             st_asgeojson
----------------------------------------------------------------------
 {"type":"LineString","coordinates":[[110,40],[2,3],[-10,80],[-7,9]]}
```

# ST\$1AsHexWKB
<a name="ST_AsHexWKB-function"></a>

ST\$1AsHexWKB 使用 ASCII 十六进制字符（0–9、A–F）返回输入几何体或地理的十六进制已知二进制 (WKB) 表示形式。对于 3DZ、3DM 和 4D 几何体或地理，ST\$1AsHexWKB 使用开放地理空间联盟 (OGC) 标准值作为几何体或地理类型。

## 语法
<a name="ST_AsHexWKB-function-syntax"></a>

```
ST_AsHexWKB(geo)
```

## 参数
<a name="ST_AsHexWKB-function-arguments"></a>

 *geo*   
一个 `GEOMETRY` 或 `GEOGRAPHY` 数据类型的值，或一个计算结果为 `GEOMETRY` 或 `GEOGRAPHY` 类型的表达式。

## 返回类型
<a name="ST_AsHexWKB-function-return"></a>

`VARCHAR`

如果 *geo* 为 null，则返回 null。

如果结果大于 64-KB `VARCHAR`，则将返回一个错误。

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

以下 SQL 返回几何体中多边形的十六进制 WKB 表示形式。

```
SELECT ST_AsHexWKB(ST_GeomFromText('POLYGON((0 0,0 1,1 1,1 0,0 0))',4326));
```

```
st_ashexwkb
--------------------------------
01030000000100000005000000000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000000000000000000000000000000000000000
```

以下 SQL 返回地理中多边形的十六进制 WKB 表示形式。

```
SELECT ST_AsHexWKB(ST_GeogFromText('POLYGON((0 0,0 1,1 1,1 0,0 0))'));
```

```
st_ashexwkb
--------------------------------
01030000000100000005000000000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000000000000000000000000000000000000000
```

# ST\$1AsHexEWKB
<a name="ST_AsHexEWKB-function"></a>

ST\$1AsHexEWKB 使用 ASCII 十六进制字符（0–9、A–F）返回输入几何体或地理的扩展的已知二进制 (WKB) 表示形式。对于 3DZ、3DM 和 4D 几何体或地理，ST\$1AsHexEWKB 使用 PostGIS 扩展 WKB 值作为几何或地理类型。

## 语法
<a name="ST_AsHexEWKB-function-syntax"></a>

```
ST_AsHexEWKB(geo)
```

## 参数
<a name="ST_AsHexEWKB-function-arguments"></a>

 *geo*   
一个 `GEOMETRY` 或 `GEOGRAPHY` 数据类型的值，或一个计算结果为 `GEOMETRY` 或 `GEOGRAPHY` 类型的表达式。

## 返回类型
<a name="ST_AsHexEWKB-function-return"></a>

`VARCHAR`

如果 *geo* 为 null，则返回 null。

如果结果大于 64-KB `VARCHAR`，则将返回一个错误。

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

以下 SQL 返回几何体中多边形的十六进制 EWKB 表示形式。

```
SELECT ST_AsHexEWKB(ST_GeomFromText('POLYGON((0 0,0 1,1 1,1 0,0 0))',4326));
```

```
st_ashexewkb
--------------------------------
0103000020E61000000100000005000000000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000000000000000000000000000000000000000
```

以下 SQL 返回地理中多边形的十六进制 EWKB 表示形式。

```
SELECT ST_AsHexEWKB(ST_GeogFromText('POLYGON((0 0,0 1,1 1,1 0,0 0))'));
```

```
st_ashexewkb
--------------------------------
0103000020E61000000100000005000000000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000000000000000000000000000000000000000
```

# ST\$1AsText
<a name="ST_AsText-function"></a>

ST\$1AsText 返回输入几何体或地理的已知文本 (WKT) 表示形式。对于 3DZ、3DM 和 4D 几何体或地理，ST\$1AsEWKT 会将 Z、M 或 ZM 附加到几何或地理类型的 WKT 值。

## 语法
<a name="ST_AsText-function-syntax"></a>

```
ST_AsText(geo)
```

```
ST_AsText(geo, precision)
```

## 参数
<a name="ST_AsText-function-arguments"></a>

 *geo*   
一个 `GEOMETRY` 或 `GEOGRAPHY` 数据类型的值，或一个计算结果为 `GEOMETRY` 或 `GEOGRAPHY` 类型的表达式。

 *精度*   
一个 数据类型的 值`INTEGER` 对于几何体，*geo* 的坐标使用指定的精度 1–20 显示。如果未指定*精度*，则默认值为 15。对于地理，*geo* 的坐标使用指定的精度显示。如果未指定*精度*，则默认值为 15。

## 返回类型
<a name="ST_AsText-function-return"></a>

`VARCHAR`

如果 *geo* 为 null，则返回 null。

如果*精度* 为 null，则返回 null。

如果结果大于 64-KB `VARCHAR`，则将返回一个错误。

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

以下 SQL 返回线串的 WKT 表示形式。

```
SELECT ST_AsText(ST_GeomFromText('LINESTRING(3.141592653589793 -6.283185307179586,2.718281828459045 -1.414213562373095)', 4326));
```

```
st_astext
--------------------------------
LINESTRING(3.14159265358979 -6.28318530717959,2.71828182845905 -1.41421356237309)
```

以下 SQL 返回线串的 WKT 表示形式。使用六位数精度显示几何体的坐标。

```
SELECT ST_AsText(ST_GeomFromText('LINESTRING(3.141592653589793 -6.283185307179586,2.718281828459045 -1.414213562373095)', 4326), 6);
```

```
st_astext
----------------------------------------------
 LINESTRING(3.14159 -6.28319,2.71828 -1.41421)
```

以下 SQL 返回地理的 WKT 表示形式。

```
SELECT ST_AsText(ST_GeogFromText('LINESTRING(110 40, 2 3, -10 80, -7 9)'));
```

```
             st_astext
------------------------------------
 LINESTRING(110 40,2 3,-10 80,-7 9)
```

# ST\$1Azimuth
<a name="ST_Azimuth-function"></a>

ST\$1Azimuth 使用两个输入点的 2D 投影返回基于北向的笛卡尔方位。

## 语法
<a name="ST_Azimuth-function-syntax"></a>

```
ST_Azimuth(point1, point2)
```

## 参数
<a name="ST_Azimuth-function-arguments"></a>

 *point1*   
一个 `POINT` 数据类型的 `GEOMETRY` 值。*point1* 的空间参考系统标识符 (SRID) 必须与 *point2* 的 SRID 匹配。

 *point2*   
一个 `POINT` 数据类型的 `GEOMETRY` 值。*point2* 的 SRID 必须与 *point1* 的 SRID 匹配。

## 返回类型
<a name="ST_Azimuth-function-return"></a>

一个数字，它表示 `DOUBLE PRECISION` 数据类型的角度（以弧度为单位）。值的范围从 0（包含）到 2 pi（不包含）。

如果 *point1* 或 *point2* 是空点，则返回一个错误。

如果 *point1* 或 *point2* 为 null，则返回 null。

如果 *point1* 和 *point2* 相等，则返回 null。

如果 *point1* 或 *point2* 不是点，则返回一个错误。

如果 *point1* 和 *point2* 不具有空间参考系统标识符 (SRID) 的值，则返回一个错误。

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

以下 SQL 返回输入点的方位。

```
SELECT ST_Azimuth(ST_Point(1,2), ST_Point(5,6));
```

```
st_azimuth
-------------------
 0.7853981633974483
```

# ST\$1Boundary
<a name="ST_Boundary-function"></a>

ST\$1Boundary 返回输入几何体的边界，如下所示：
+ 如果输入几何体为空（即，它不包含点），则按原样返回。
+ 如果输入几何是点或非空多点，则返回空几何体集合。
+ 如果输入是线串或多线串，则返回包含边界上所有点的多点。多点可能为空）。
+ 如果输入是一个没有任何内环的面，则返回一个表示其边界的闭合线串。
+ 如果输入是具有内环的面，或者是多面，则返回多线串。多线串包含平面几何体中所有环的所有边界，作为闭合线串。

为了确定点相等性，ST\$1Boundary 会对输入几何体的 2D 投影进行操作。如果输入几何体为空，则返回该几何体的维度与输入相同的副本。对于非空 3DM 和 4D 几何体，其 `m` 坐标会被删除。在 3DZ 和 4D 多线串的特殊情况下，多线串边界点的 `z` 坐标被计算为具有相同 2D 投影的线串边界点的不同 z 值的平均值。

## 语法
<a name="ST_Boundary-function-syntax"></a>

```
ST_Boundary(geom)
```

## 参数
<a name="ST_Boundary-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Boundary-function-return"></a>

`GEOMETRY`

如果 *geom* 为 null，则返回 null。

如果 *geom* 为 `GEOMETRYCOLLECTION`，则返回一个错误。

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

以下 SQL 返回输入多边形的边界，作为多线串。

```
SELECT ST_AsEWKT(ST_Boundary(ST_GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,1 2,2 1,1 1))')));
```

```
st_asewkt
--------------------
 MULTILINESTRING((0 0,10 0,10 10,0 10,0 0),(1 1,1 2,2 1,1 1))
```

# ST\$1Buffer
<a name="ST_Buffer-function"></a>

ST\$1Buffer 返回 2D 几何体，该几何表示与 xy 笛卡尔平面上投影的输入几何体之间的距离小于或等于输入距离的所有点。

## 语法
<a name="ST_Buffer-function-syntax"></a>

```
ST_Buffer(geom, distance)
```

```
ST_Buffer(geom, distance, number_of_segments_per_quarter_circle)
```

## 参数
<a name="ST_Buffer-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *distance*   
数据类型 `DOUBLE PRECISION` 的值表示缓冲区的距离（或半径）。

 *number\$1of\$1segments\$1per\$1quarter\$1circle*   
数据类型 `INTEGER` 的值。此值确定了围绕输入几何体的每个顶点大致四分之一圆的点数。负值默认为零。默认值为 8。

## 返回类型
<a name="ST_Buffer-function-return"></a>

`GEOMETRY`

ST\$1Buffer 函数返回 xy 笛卡尔平面中的二维 (2D) 几何体。

如果 *geom* 为 `GEOMETRYCOLLECTION`，则返回一个错误。

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

以下 SQL 返回输入线串的缓冲区。

```
SELECT ST_AsEwkt(ST_Buffer(ST_GeomFromText('LINESTRING(1 2,5 2,5 8)'), 2));
```

```
               st_asewkt  
POLYGON((-1 2,-0.96157056080646 2.39018064403226,-0.847759065022573 2.76536686473018,-0.662939224605089 3.11114046603921,-0.414213562373093 3.4142135623731,-0.111140466039201 3.66293922460509,0.234633135269824 3.84775906502257,0.609819355967748 3.96157056080646,1 4,3 4,3 8,3.03842943919354 8.39018064403226,3.15224093497743 8.76536686473018,3.33706077539491 9.11114046603921,3.58578643762691 9.4142135623731,3.8888595339608 9.66293922460509,4.23463313526982 9.84775906502257,4.60981935596775 9.96157056080646,5 10,5.39018064403226 9.96157056080646,5.76536686473018 9.84775906502257,6.11114046603921 9.66293922460509,6.4142135623731 9.41421356237309,6.66293922460509 9.1111404660392,6.84775906502258 8.76536686473017,6.96157056080646 8.39018064403225,7 8,7 2,6.96157056080646 1.60981935596774,6.84775906502257 1.23463313526982,6.66293922460509 0.888859533960796,6.41421356237309 0.585786437626905,6.1111404660392 0.33706077539491,5.76536686473018 0.152240934977427,5.39018064403226 0.0384294391935391,5 0,1 0,0.609819355967744 0.0384294391935391,0.234633135269821 0.152240934977427,-0.111140466039204 0.337060775394909,-0.414213562373095 0.585786437626905,-0.662939224605091 0.888859533960796,-0.847759065022574 1.23463313526982,-0.961570560806461 1.60981935596774,-1 2))
```

以下 SQL 返回输入点几何体的缓冲区，该缓冲区大致为一个圆。由于该命令没有指定每个四分之一圆的区段数，因此该函数使用八个区段的默认值表示约四分之一圆。

```
SELECT ST_AsEwkt(ST_Buffer(ST_GeomFromText('POINT(3 4)'), 2));
```

```
               st_asewkt
POLYGON((1 4,1.03842943919354 4.39018064403226,1.15224093497743 4.76536686473018,1.33706077539491 5.11114046603921,1.58578643762691 5.4142135623731,1.8888595339608 5.66293922460509,2.23463313526982 5.84775906502257,2.60981935596775 5.96157056080646,3 6,3.39018064403226 5.96157056080646,3.76536686473019 5.84775906502257,4.11114046603921 5.66293922460509,4.4142135623731 5.41421356237309,4.66293922460509 5.1111404660392,4.84775906502258 4.76536686473017,4.96157056080646 4.39018064403225,5 4,4.96157056080646 3.60981935596774,4.84775906502257 3.23463313526982,4.66293922460509 2.8888595339608,4.41421356237309 2.58578643762691,4.1111404660392 2.33706077539491,3.76536686473018 2.15224093497743,3.39018064403226 2.03842943919354,3 2,2.60981935596774 2.03842943919354,2.23463313526982 2.15224093497743,1.8888595339608 2.33706077539491,1.58578643762691 2.58578643762691,1.33706077539491 2.8888595339608,1.15224093497743 3.23463313526982,1.03842943919354 3.60981935596774,1 4))
```

以下 SQL 返回输入点几何体的缓冲区，该缓冲区大致为一个圆。由于该命令指定 3 作为每个四分之一圆的区段数，因此该函数使用三个区段表示约四分之一圆。

```
SELECT ST_AsEwkt(ST_Buffer(ST_GeomFromText('POINT(3 4)'), 2, 3));
```

```
               st_asewkt
POLYGON((1 4,1.26794919243112 5,2 5.73205080756888,3 6,4 5.73205080756888,4.73205080756888 5,5 4,4.73205080756888 3,4 2.26794919243112,3 2,2 2.26794919243112,1.26794919243112 3,1 4))
```

# ST\$1Centroid
<a name="ST_Centroid-function"></a>

ST\$1Centroid 返回一个表示几何体质心的点，如下所示：
+ 对于 `POINT` 几何体，它返回坐标为几何体中点坐标平均值的点。
+ 对于 `LINESTRING` 几何体，它返回坐标是几何体分段中点的加权平均值的点，其中权重是几何体分段的长度。
+ 对于 `POLYGON` 几何体，它返回坐标是平面几何体的三角测量的质心的加权平均值的点，其中权重是三角测量中三角形的面积。
+ 对于几何体集合，它返回几何体集合中具有最大拓扑维度的几何体的质心的加权平均值。

## 语法
<a name="ST_Centroid-function-syntax"></a>

```
ST_Centroid(geom)
```

## 参数
<a name="ST_Centroid-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Centroid-function-return"></a>

`GEOMETRY` 

如果 *geom* 为 null，则返回 null。

如果 *geom* 为空，则返回 null。

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

以下 SQL 从输入线串返回中心点。

```
SELECT ST_AsEWKT(ST_Centroid(ST_GeomFromText('LINESTRING(110 40, 2 3, -10 80, -7 9, -22 -33)', 4326)))
```

```
                     st_asewkt
----------------------------------------------------
 SRID=4326;POINT(15.6965103455214 27.0206782881905)
```

# ST\$1Collect
<a name="ST_Collect-function"></a>

ST\$1Collect 有两个变体。一个接受两个几何体，一个接受聚合表达式。

ST\$1Collect 的第一个变体从输入几何体中创建几何体。输入几何体的顺序将保留。此变体的原理如下：
+ 如果两个输入几何体都是点，则返回具有两个点的 `MULTIPOINT`。
+ 如果两个输入几何体都是线串，则返回具有两个线串的 `MULTILINESTRING`。
+ 如果两个输入几何体都是面，则返回具有两个面的 `MULTIPOLYGON`。
+ 否则，返回具有两个输入几何体的 `GEOMETRYCOLLECTION`。

ST\$1Collect 的第二个变体从几何体列中的几何体创建几何体。没有确定的几何体返回顺序。指定 WITHIN GROUP (ORDER BY ...) 子句以指定返回几何体的顺序。此变体的原理如下：
+ 如果输入聚合表达式中的所有非 NULL 行都是点，则返回包含聚合表达式中所有点的多点。
+ 如果聚合表达式中的所有非 NULL 行都是线串，则返回包含聚合表达式中所有线串的多线串。
+ 如果聚合表达式中的所有非 NULL 行都是面，则返回一个包含聚合表达式中所有面的多面。
+ 否则，返回包含聚合表达式中的所有几何体的 `GEOMETRYCOLLECTION`。

ST\$1Collect 返回与输入几何体具有相同维度的几何体。所有的输入几何体必须具有相同的维度。

## 语法
<a name="ST_Collect-function-syntax"></a>

```
ST_Collect(geom1, geom2)
```

```
ST_Collect(aggregate_expression)  [WITHIN GROUP (ORDER BY sort_expression1 [ASC | DESC] [, sort_expression2 [ASC | DESC] ...])]
```

## 参数
<a name="ST_Collect-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *aggregate\$1expression*   
数据类型 `GEOMETRY` 的列，或一个计算结果为 `GEOMETRY` 类型的表达式。

 [WITHIN GROUP (ORDER BY *sort\$1expression1* [ASC \$1 DESC] [, *sort\$1expression2* [ASC \$1 DESC] ...])]   
用于指定聚合值的排序顺序的可选子句。ORDER BY 子句包含排序表达式的列表。排序表达式是类似于查询选择列表中的有效排序表达式（如列名）的表达式。您可以指定升序 (`ASC`) 或降序 (`DESC`) 顺序。默认为 `ASC`。

## 返回类型
<a name="ST_Collect-function-return"></a>

子类型 `MULTIPOINT`、`MULTILINESTRING`、`MULTIPOLYGON` 或 `GEOMETRYCOLLECTION`的 `GEOMETRY`。

返回的几何体的空间参考系统标识符 (SRID) 值是输入几何体的 SRID 值。

如果 *geom1* 或 *geom2* 均为 null，则返回 null。

如果 *aggregate\$1expression* 的所有行均为 null，则返回 null。

如果 *geom1* 为 null，则返回 *geom2* 的副本。同样，如果 *geom2* 为 null，则返回 *geom1* 的副本。

如果 *geom1* 和 *geom2* 具有不同的 SRID 值，则返回一个错误。

如果 *aggregate\$1expression* 中的两个几何体具有不同的 SRID 值，则返回一个错误。

如果返回的几何体大于 `GEOMETRY` 最大大小，则返回一个错误。

如果 *geom1* 和 *geom2* 具有不同的维度，则返回一个错误。

如果 *aggregate\$1expression* 中的两个几何体具有不同的维度，则返回一个错误。

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

以下 SQL 返回包含两个输入几何体的几何体集合。

```
SELECT ST_AsText(ST_Collect(ST_GeomFromText('LINESTRING(0 0,1 1)'), ST_GeomFromText('POLYGON((10 10,20 10,10 20,10 10))')));
```

```
st_astext
-----------
 GEOMETRYCOLLECTION(LINESTRING(0 0,1 1),POLYGON((10 10,20 10,10 20,10 10)))
```

以下 SQL 将表中的所有几何体收集到几何体集合中。

```
WITH tbl(g) AS (SELECT ST_GeomFromText('POINT(1 2)', 4326) UNION ALL
SELECT ST_GeomFromText('LINESTRING(0 0,10 0)', 4326) UNION ALL
SELECT ST_GeomFromText('MULTIPOINT(13 4,8 5,4 4)', 4326) UNION ALL
SELECT NULL::geometry UNION ALL
SELECT ST_GeomFromText('POLYGON((0 0,10 0,0 10,0 0))', 4326))
SELECT ST_AsEWKT(ST_Collect(g)) FROM tbl;
```

```
st_astext
-----------
 SRID=4326;GEOMETRYCOLLECTION(POINT(1 2),LINESTRING(0 0,10 0),MULTIPOINT((13 4),(8 5),(4 4)),POLYGON((0 0,10 0,0 10,0 0)))
```

以下 SQL 收集表中按 id 列分组并按此 ID 排序的所有几何体。在此示例中，生成的几何体按 ID 分组，如下所示：
+ id 1 – 多点钟的点。
+ id 2 – 多线串中的线串。
+ id 3 – 几何体集合中的混合子类型。
+ id 4 – 多面中的面。
+ id 5 – null，且结果为 null。

```
WITH tbl(id, g) AS (SELECT 1, ST_GeomFromText('POINT(1 2)', 4326) UNION ALL
SELECT 1, ST_GeomFromText('POINT(4 5)', 4326) UNION ALL
SELECT 2, ST_GeomFromText('LINESTRING(0 0,10 0)', 4326) UNION ALL
SELECT 2, ST_GeomFromText('LINESTRING(10 0,20 -5)', 4326) UNION ALL
SELECT 3, ST_GeomFromText('MULTIPOINT(13 4,8 5,4 4)', 4326) UNION ALL
SELECT 3, ST_GeomFromText('MULTILINESTRING((-1 -1,-2 -2),(-3 -3,-5 -5))', 4326) UNION ALL
SELECT 4, ST_GeomFromText('POLYGON((0 0,10 0,0 10,0 0))', 4326) UNION ALL
SELECT 4, ST_GeomFromText('POLYGON((20 20,20 30,30 20,20 20))', 4326) UNION ALL
SELECT 1, NULL::geometry UNION ALL SELECT 2, NULL::geometry UNION ALL
SELECT 5, NULL::geometry UNION ALL SELECT 5, NULL::geometry)
SELECT id, ST_AsEWKT(ST_Collect(g)) FROM tbl GROUP BY id ORDER BY id;
```

```
 id |                                                 st_asewkt                                                 
----+-----------------------------------------------------------------------------------------------------------
  1 | SRID=4326;MULTIPOINT((1 2),(4 5))
  2 | SRID=4326;MULTILINESTRING((0 0,10 0),(10 0,20 -5))
  3 | SRID=4326;GEOMETRYCOLLECTION(MULTIPOINT((13 4),(8 5),(4 4)),MULTILINESTRING((-1 -1,-2 -2),(-3 -3,-5 -5)))
  4 | SRID=4326;MULTIPOLYGON(((0 0,10 0,0 10,0 0)),((20 20,20 30,30 20,20 20)))
  5 |
```

以下 SQL 将表中的所有几何体收集到几何体集合中。结果根据 `id` 按降序排序，然后根据它们的最小和最大 x 坐标按字典顺序排序。

```
WITH tbl(id, g) AS (
SELECT 1, ST_GeomFromText('POINT(4 5)', 4326) UNION ALL
SELECT 1, ST_GeomFromText('POINT(1 2)', 4326) UNION ALL
SELECT 2, ST_GeomFromText('LINESTRING(10 0,20 -5)', 4326) UNION ALL
SELECT 2, ST_GeomFromText('LINESTRING(0 0,10 0)', 4326) UNION ALL
SELECT 3, ST_GeomFromText('MULTIPOINT(13 4,8 5,4 4)', 4326) UNION ALL
SELECT 3, ST_GeomFromText('MULTILINESTRING((-1 -1,-2 -2),(-3 -3,-5 -5))', 4326) UNION ALL
SELECT 4, ST_GeomFromText('POLYGON((20 20,20 30,30 20,20 20))', 4326) UNION ALL
SELECT 4, ST_GeomFromText('POLYGON((0 0,10 0,0 10,0 0))', 4326) UNION ALL
SELECT 1, NULL::geometry UNION ALL SELECT 2, NULL::geometry UNION ALL
SELECT 5, NULL::geometry UNION ALL SELECT 5, NULL::geometry)
SELECT ST_AsEWKT(ST_Collect(g) WITHIN GROUP (ORDER BY id DESC, ST_XMin(g), ST_XMax(g))) FROM tbl;
```

```
                                                                                                                  st_asewkt                                                                                                                  
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 SRID=4326;GEOMETRYCOLLECTION(POLYGON((0 0,10 0,0 10,0 0)),POLYGON((20 20,20 30,30 20,20 20)),MULTILINESTRING((-1 -1,-2 -2),(-3 -3,-5 -5)),MULTIPOINT((13 4),(8 5),(4 4)),LINESTRING(0 0,10 0),LINESTRING(10 0,20 -5),POINT(1 2),POINT(4 5)
```

# ST\$1Contains
<a name="ST_Contains-function"></a>

如果第一个输入几何体的 2D 投影包含第二个输入几何体的 2D 投影，则 ST\$1Contains 返回 true。如果 `A` 中的每个点均为 `B` 中的一个点，并且其内部有非空相交区域，则几何体 `B` 包含几何体 `A`。

ST\$1Contains(`A`, `B`) 与 ST\$1Within(`B`, `A`) 等效。

## 语法
<a name="ST_Contains-function-syntax"></a>

```
ST_Contains(geom1, geom2)
```

## 参数
<a name="ST_Contains-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。此值将与 *geom1* 进行比较以确定它是否包含在 *geom1* 中。

## 返回类型
<a name="ST_Contains-function-return"></a>

`BOOLEAN`

如果 *geom1* 或 *geom2* 为 null，则返回 null。

如果 *geom1* 和 *geom2* 不具有相同的空间参考系统标识符 (SRID) 值，则返回一个错误。

如果 *geom1* 或 *geom2* 为几何体集合，则返回一个错误。

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

以下 SQL 检查第一个多边形是否包含第二个多边形。

```
SELECT ST_Contains(ST_GeomFromText('POLYGON((0 2,1 1,0 -1,0 2))'), ST_GeomFromText('POLYGON((-1 3,2 1,0 -3,-1 3))'));
```

```
st_contains
-----------
 false
```

# ST\$1ContainsProperly
<a name="ST_ContainsProperly-function"></a>

如果两个输入几何体都为非空，并且第二个几何体的 2D 投影的所有点都是第一个几何体的 2D 投影的内部点，则 ST\$1ContainsProperly 返回 true。

## 语法
<a name="ST_ContainsProperly-function-syntax"></a>

```
ST_ContainsProperly(geom1, geom2)
```

## 参数
<a name="ST_ContainsProperly-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型不能为 `GEOMETRYCOLLECTION`。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型不能为 `GEOMETRYCOLLECTION`。将此值与 *geom1* 进行比较，以确定其所有点是否都是 *geom1* 的内点。

## 返回类型
<a name="ST_ContainsProperly-function-return"></a>

`BOOLEAN`

如果 *geom1* 或 *geom2* 为 null，则返回 null。

如果 *geom1* 和 *geom2* 不具有相同的空间参考系统标识符 (SRID) 值，则返回一个错误。

如果 *geom1* 或 *geom2* 为几何体集合，则返回一个错误。

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

在输入线串与输入面的内部和边界（但不是其外部）相交的位置，以下 SQL 返回 ST\$1Contains 和 ST\$1ContainsProperly 的值。面包含线串，但没有正确包含线串。

```
WITH tmp(g1, g2) 
AS (SELECT ST_GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0))'), ST_GeomFromText('LINESTRING(5 5,10 5,10 6,5 5)')) SELECT ST_Contains(g1, g2), ST_ContainsProperly(g1, g2) 
FROM tmp;
```

```
 st_contains | st_containsproperly 
-------------+---------------------
 t           | f
```

# ST\$1ConvexHull
<a name="ST_ConvexHull-function"></a>

ST\$1ConvexHull 返回一个几何体，该几何体表示输入几何体中包含的非空点的凸包。

对于空输入，生成的几何体与输入几何体相同。对于所有非空输入，该函数在输入几何体的 2D 投影上运行。但是，输出几何体的维度取决于输入几何体的维度。更具体地说，当输入几何体为非空 3DM 或 3D 几何体时，`m` 坐标将被删除。也就是说，返回的几何体的维度分别为 2D 或 3DZ。如果输入为非空 2D 或 3DZ 几何体，则生成的几何体具有相同的维度。

## 语法
<a name="ST_ConvexHull-function-syntax"></a>

```
ST_ConvexHull(geom)
```

## 参数
<a name="ST_ConvexHull-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_ConvexHull-function-return"></a>

`GEOMETRY`

返回的几何体的空间参考系统标识符 (SRID) 值是输入几何体的 SRID 值。

如果 *geom* 为 null，则返回 null。

返回的值如下所示。


| 凸包上的点数 | 几何体子类型 | 
| --- | --- | 
| 0 | 返回 *geom* 的副本。 | 
| 1 | 返回子类型 `POINT`。 | 
| 2 | 返回子类型 `LINESTRING`。返回线串的两个点按字典顺序排序。 | 
| 3 或更大 | 返回不具有内环的 `POLYGON` 子类型。面是顺时针方向的，外环的第一个点是按字典顺序排列的环的最小点。 | 

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

以下 SQL 返回线串的扩展已知文本 (EWKT) 表示形式。在本例中，返回的凸包是面。

```
SELECT ST_AsEWKT(ST_ConvexHull(ST_GeomFromText('LINESTRING(0 0,1 0,0 1,1 1,0.5 0.5)'))) as output;
```

```
output
-------------
POLYGON((0 0,0 1,1 1,1 0,0 0))
```

以下 SQL 返回线串的 EWKT 表示形式。在本例中，返回的凸包是线串。

```
SELECT ST_AsEWKT(ST_ConvexHull(ST_GeomFromText('LINESTRING(0 0,1 1,0.2 0.2,0.6 0.6,0.5 0.5)'))) as output;
```

```
output
-------------
LINESTRING(0 0,1 1)
```

以下 SQL 返回多点的 EWKT 表示形式。在本例中，返回的凸包是点。

```
SELECT ST_AsEWKT(ST_ConvexHull(ST_GeomFromText('MULTIPOINT(0 0,0 0,0 0)'))) as output;
```

```
output
-------------
POINT(0 0)
```

# ST\$1CoveredBy
<a name="ST_CoveredBy-function"></a>

如果第一个输入几何体的 2D 投影被第二个输入几何体的 2D 投影覆盖，则 ST\$1CoveredBy 返回 true。如果几何体 `A` 和几何体 `B` 都是非空的，并且 `A` 中的每个点均为 `B` 中的一个点，则前者被后者覆盖。

ST\$1CoveredBy(`A`, `B`) 与 ST\$1Covers(`B`, `A`) 等效。

## 语法
<a name="ST_CoveredBy-function-syntax"></a>

```
ST_CoveredBy(geom1, geom2)
```

## 参数
<a name="ST_CoveredBy-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。此值将与 *geom2* 进行比较以确定它是否被 *geom2* 覆盖。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_CoveredBy-function-return"></a>

`BOOLEAN`

如果 *geom1* 或 *geom2* 为 null，则返回 null。

如果 *geom1* 和 *geom2* 不具有相同的空间参考系统标识符 (SRID) 值，则返回一个错误。

如果 *geom1* 或 *geom2* 为几何体集合，则返回一个错误。

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

以下 SQL 检查第一个多边形是否被第二个多边形覆盖。

```
SELECT ST_CoveredBy(ST_GeomFromText('POLYGON((0 2,1 1,0 -1,0 2))'), ST_GeomFromText('POLYGON((-1 3,2 1,0 -3,-1 3))'));
```

```
st_coveredby
-----------
 true
```

# ST\$1Covers
<a name="ST_Covers-function"></a>

如果第一个输入几何体的 2D 投影被第二个输入几何体的 2D 投影覆盖，则 ST\$1Covers 返回 true。如果几何体 `A` 和几何体 `B` 都是非空的，并且 `B` 中的每个点均为 `A` 中的一个点，则前者覆盖了后者。

ST\$1Covers(`A`, `B`) 与 ST\$1CoveredBy(`B`, `A`) 等效。

## 语法
<a name="ST_Covers-function-syntax"></a>

```
ST_Covers(geom1, geom2)
```

## 参数
<a name="ST_Covers-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。此值将与 *geom1*进行比较以确定它是否覆盖了 *geom1*。

## 返回类型
<a name="ST_Covers-function-return"></a>

`BOOLEAN`

如果 *geom1* 或 *geom2* 为 null，则返回 null。

如果 *geom1* 和 *geom2* 不具有相同的空间参考系统标识符 (SRID) 值，则返回一个错误。

如果 *geom1* 或 *geom2* 为几何体集合，则返回一个错误。

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

以下 SQL 检查第一个多边形是否覆盖了第二个多边形。

```
SELECT ST_Covers(ST_GeomFromText('POLYGON((0 2,1 1,0 -1,0 2))'), ST_GeomFromText('POLYGON((-1 3,2 1,0 -3,-1 3))'));
```

```
st_covers
-----------
 false
```

# ST\$1Crosses
<a name="ST_Crosses-function"></a>

如果两个输入几何体的 2D 投影相互交叉，ST\$1Crosses 将返回 true。

## 语法
<a name="ST_Crosses-function-syntax"></a>

```
ST_Crosses(geom1, geom2)
```

## 参数
<a name="ST_Crosses-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Crosses-function-return"></a>

`BOOLEAN`

如果 *geom1* 或 *geom2* 为 null，则返回一个错误。

如果 *geom1* 或 *geom2* 为几何体集合，则返回一个错误。

如果 *geom1* 和 *geom2* 不具有相同的空间参考系统标识符 (SRID) 值，则返回一个错误。

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

以下 SQL 检查第一个面是否与第二个多点相交。在此示例中，多点与面的内部和外部相交，这就是 ST\$1Crosses返回 true 的原因。

```
SELECT ST_Crosses (ST_GeomFromText('polygon((0 0,10 0,10 10,0 10,0 0))'), ST_GeomFromText('multipoint(5 5,0 0,-1 -1)'));
```

```
st_crosses              
-------------
 true
```

以下 SQL 检查第一个面是否与第二个多点相交。在此示例中，多点与面的外部相交，而不是其内部相交，这就是 ST\$1Crosses 返回 false 的原因。

```
SELECT ST_Crosses (ST_GeomFromText('polygon((0 0,10 0,10 10,0 10,0 0))'), ST_GeomFromText('multipoint(0 0,-1 -1)'));
```

```
st_crosses              
-------------
 false
```

# ST\$1Dimension
<a name="ST_Dimension-function"></a>

ST\$1Dimension 返回输入几何体的固有维度。*固有维度* 是几何体中定义的子类型的维度值。

对于 3DM、3DZ 和 4D 几何体输入，ST\$1Dimension 返回的结果与 2D 几何体输入的结果相同。

## 语法
<a name="ST_Dimension-function-syntax"></a>

```
ST_Dimension(geom)
```

## 参数
<a name="ST_Dimension-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Dimension-function-return"></a>

`INTEGER`，表示 *geom* 的固有维度。

如果 *geom* 为 null，则返回 null。

返回的值如下所示。


| 返回的值 | 几何体子类型 | 
| --- | --- | 
| 0 | 在 *geom* 为 `POINT` 或 `MULTIPOINT` 子类型时返回 | 
| 1 | 在 *geom* 为 `LINESTRING` 或 `MULTILINESTRING` 子类型时返回。 | 
| 2 | 在 *geom* 为 `POLYGON` 或 `MULTIPOLYGON` 子类型时返回 | 
| 0 | 在 *geom* 为空 `GEOMETRYCOLLECTION` 子类型时返回 | 
| 集合组件的最大维度 | 在 *geom* 为 `GEOMETRYCOLLECTION` 子类型时返回 | 

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

以下 SQL 将四点 LINESTRING 的已知文本 (WKT) 表示形式转换为 GEOMETRY 对象，并返回线串的维度。

```
SELECT ST_Dimension(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'));
```

```
st_dimension
-------------
1
```

# ST\$1Disjoint
<a name="ST_Disjoint-function"></a>

如果两个输入几何体的 2D 投影没有共同点，则 ST\$1Disjoint 返回 true。

## 语法
<a name="ST_Disjoint-function-syntax"></a>

```
ST_Disjoint(geom1, geom2)
```

## 参数
<a name="ST_Disjoint-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Disjoint-function-return"></a>

`BOOLEAN`

如果 *geom1* 或 *geom2* 为 null，则返回 null。

如果 *geom1* 和 *geom2* 不具有相同的空间参考系统标识符 (SRID) 值，则返回一个错误。

如果 *geom1* 或 *geom2* 为几何体集合，则返回一个错误。

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

以下 SQL 检查第一个多边形是否与第二个多边形不相交。

```
SELECT ST_Disjoint(ST_GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),(2 2,2 5,5 5,5 2,2 2))'), ST_Point(4, 4));
```

```
st_disjoint               
-----------
 true
```

# ST\$1Distance
<a name="ST_Distance-function"></a>

对于输入几何体，ST\$1Distance 返回两个输入几何体值的 2D 投影之间的最小欧氏距离。

对于 3DM、3DZ、4D 几何体，ST\$1Distance 返回两个输入几何体值的 2D 投影之间的欧氏距离。

对于输入地理，ST\$1Distance 返回两个 2D 点的测地线距离。距离以米为单位。对于点和空点以外的地理，将返回错误。

## 语法
<a name="ST_Distance-function-syntax"></a>

```
ST_Distance(geo1, geo2)
```

## 参数
<a name="ST_Distance-function-arguments"></a>

 *geo1*   
一个 `GEOMETRY` 或 `GEOGRAPHY` 数据类型的值，或一个计算结果为 `GEOMETRY` 或 `GEOGRAPHY` 类型的表达式。*geo1* 的数据类型必须与 *geo2* 相同。

 *geo2*   
一个 `GEOMETRY` 或 `GEOGRAPHY` 数据类型的值，或一个计算结果为 `GEOMETRY` 或 `GEOGRAPHY` 类型的表达式。*geo2* 的数据类型必须与 *geo1* 相同。

## 返回类型
<a name="ST_Distance-function-return"></a>

`DOUBLE PRECISION`，采用与输入几何体或地理相同的单位。

如果 *geo1* 或 *geo2* 为 null 或为空，则返回 null。

如果 *geo1* 和 *geo2* 不具有相同的空间参考系统标识符 (SRID) 值，则返回一个错误。

如果 *geo1* 或 *geo2* 为几何体集合，则返回一个错误。

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

以下 SQL 返回两个多边形之间的距离。

```
SELECT ST_Distance(ST_GeomFromText('POLYGON((0 2,1 1,0 -1,0 2))'), ST_GeomFromText('POLYGON((-1 -3,-2 -1,0 -3,-1 -3))'));
```

```
  st_distance
-----------
1.4142135623731
```

以下 SQL 使用 GEOGRAPHY 数据类型返回勃兰登堡门和柏林国会大厦之间的距离（以米为单位）。

```
SELECT ST_Distance(ST_GeogFromText('POINT(13.37761826722198 52.516411678282445)'), ST_GeogFromText('POINT(13.377950831464005 52.51705102546893)'));
```

```
   st_distance
------------------
 74.64129172609631
```

# ST\$1DistanceSphere
<a name="ST_DistanceSphere-function"></a>

ST\$1DistanceSphere 返回位于球体上的两个点几何体之间的距离。

## 语法
<a name="ST_DistanceSphere-function-syntax"></a>

```
ST_DistanceSphere(geom1, geom2)
```

```
ST_DistanceSphere(geom1, geom2, radius)
```

## 参数
<a name="ST_DistanceSphere-function-arguments"></a>

 *geom1*   
位于球体上的数据类型 `GEOMETRY` 的点值（以度为单位）。该点的第一个坐标是经度值。该点的第二个坐标是纬度值。对于 3DZ、3DM 或 4D 几何体，仅使用前两个坐标。

 *geom2*   
位于球体上的数据类型 `GEOMETRY` 的点值（以度为单位）。该点的第一个坐标是经度值。该点的第二个坐标是纬度值。对于 3DZ、3DM 或 4D 几何体，仅使用前两个坐标。

 *radius*   
数据类型 `DOUBLE PRECISION` 的球体半径。如果未提供 *radius*，则球体默认为地球，并且半径是根据椭球体的世界大地测量系统 (WGS) 84 表示形式来计算的。

## 返回类型
<a name="ST_DistanceSphere-function-return"></a>

`DOUBLE PRECISION`，采用与半径相同的单位。如果未提供半径，则距离以米为单位。

如果 *geom1* 或 *geom2* 为 null 或为空，则返回 null。

如果未提供 *radius*，则结果是沿地球表面的米数。

如果 *radius* 是负数，则返回一个错误。

如果 *geom1* 和 *geom2* 不具有相同的空间参考系统标识符 (SRID) 值，则返回一个错误。

如果 *geom1* 或 *geom2* 不是点，则返回一个错误。

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

以下示例 SQL 计算地球上两点之间的距离（以千米为单位）。

```
SELECT ROUND(ST_DistanceSphere(ST_Point(-122, 47), ST_Point(-122.1, 47.1))/ 1000, 0);
```

```
  round
-----------
 13
```

以下示例 SQL 计算位于德国的三个机场位置之间的距离（以公里为单位）：Berlin Tegel (TXL)、Munich International (MUC) 和 Frankfurt International (FRA)。

```
WITH airports_raw(code,lon,lat) AS (
(SELECT 'MUC', 11.786111, 48.353889) UNION
(SELECT 'FRA', 8.570556, 50.033333) UNION
(SELECT 'TXL', 13.287778, 52.559722)),
airports1(code,location) AS (SELECT code, ST_Point(lon, lat) FROM airports_raw),
airports2(code,location) AS (SELECT * from airports1)
SELECT (airports1.code || ' <-> ' || airports2.code) AS airports,
round(ST_DistanceSphere(airports1.location, airports2.location) / 1000, 0) AS distance_in_km
FROM airports1, airports2 WHERE airports1.code < airports2.code ORDER BY 1;
```

```
  airports   | distance_in_km 
-------------+----------------
 FRA <-> MUC |            299
 FRA <-> TXL |            432
 MUC <-> TXL |            480
```

# ST\$1DWithin
<a name="ST_DWithin-function"></a>

如果两个输入几何体值的 2D 投影之间的欧氏距离不大于阈值，则 ST\$1DWithin 返回 true。

## 语法
<a name="ST_DWithin-function-syntax"></a>

```
ST_DWithin(geom1, geom2, threshold)
```

## 参数
<a name="ST_DWithin-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *threshold*   
一个 数据类型的 值`DOUBLE PRECISION` 该值用输入参数的单位表示。

## 返回类型
<a name="ST_DWithin-function-return"></a>

`BOOLEAN`

如果 *geom1* 或 *geom2* 为 null，则返回 null。

如果 *threshold* 为负数，则返回一个错误。

如果 *geom1* 和 *geom2* 不具有相同的空间参考系统标识符 (SRID) 值，则返回一个错误。

如果 *geom1* 或 *geom2* 为几何体集合，则返回一个错误。

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

以下 SQL 检查两个多边形之间的距离是否在 5 个单位内。

```
SELECT ST_DWithin(ST_GeomFromText('POLYGON((0 2,1 1,0 -1,0 2))'), ST_GeomFromText('POLYGON((-1 3,2 1,0 -3,-1 3))'),5);
```

```
st_dwithin
-----------
 true
```

# ST\$1EndPoint
<a name="ST_EndPoint-function"></a>

ST\$1EndPoint 返回输入线串的最后一个点。结果的空间参考系统标识符 (SRID) 值与输入几何体的相同。返回的几何体的维度与输入几何体的维度相同。

## 语法
<a name="ST_EndPoint-function-syntax"></a>

```
ST_EndPoint(geom)
```

## 参数
<a name="ST_EndPoint-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `LINESTRING`。

## 返回类型
<a name="ST_EndPoint-function-return"></a>

`GEOMETRY` 

如果 *geom* 为 null，则返回 null。

如果 *geom* 为空，则返回 null。

如果 *geom* 不是 `LINESTRING`，则返回 null。

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

以下 SQL 将四点 `LINESTRING` 的扩展的已知文本 (EWKT) 表示形式返回到 `GEOMETRY` 对象，并返回线串的终点。

```
SELECT ST_AsEWKT(ST_EndPoint(ST_GeomFromText('LINESTRING(0 0,10 0,10 10,5 5,0 5)',4326)));
```

```
st_asewkt
-------------
 SRID=4326;POINT(0 5)
```

# ST\$1Envelope
<a name="ST_Envelope-function"></a>

ST\$1Envelope 返回输入几何体的最小边界框，如下所示：
+ 如果输入几何体为空，则返回的几何体是输入几何体的副本。
+ 如果输入几何体的最小边界框退化为一个点，则返回的几何体是一个点。
+ 如果输入几何体的最小边界框是一维的，则返回两点线串。
+ 如果上述条件都不成立，则函数将返回一个顺时针方向的多边形，其顶点为最小边界框的角。

返回的几何体的空间参考系统标识符 (SRID) 与输入几何体的相同。

对于所有非空输入，该函数在输入几何体的 2D 投影上运行。

## 语法
<a name="ST_Envelope-function-syntax"></a>

```
ST_Envelope(geom)
```

## 参数
<a name="ST_Envelope-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Envelope-function-return"></a>

`GEOMETRY` 

如果 *geom* 为 null，则返回 null。

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

以下 SQL 将四点 `LINESTRING` 的已知文本 (WKT) 表示形式转换为 `GEOMETRY` 对象，并返回其顶点为最小边界框的角的多边形。

```
SELECT ST_AsText(ST_Envelope(ST_GeomFromText('GEOMETRYCOLLECTION(POLYGON((0 0,10 0,0 10,0 0)),LINESTRING(20 10,20 0,10 0))')));
```

```
    st_astext
------------------------------------
  POLYGON((0 0,0 10,20 10,20 0,0 0))
```

# ST\$1Equals
<a name="ST_Equals-function"></a>

如果输入几何体的 2D 投影在几何上相等，则 ST\$1Equals 返回 true。如果几何体具有相等的点集且其内部具有非空相交区域，则将几何体视为在几何上相等。

## 语法
<a name="ST_Equals-function-syntax"></a>

```
ST_Equals(geom1, geom2)
```

## 参数
<a name="ST_Equals-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。此值将与 *geom1*进行比较以确定它是否等于 *geom1*。

## 返回类型
<a name="ST_Equals-function-return"></a>

`BOOLEAN`

如果 *geom1* 或 *geom2* 为 null，则返回一个错误。

如果 *geom1* 和 *geom2* 不具有相同的空间参考系统标识符 (SRID) 值，则返回一个错误。

如果 *geom1* 或 *geom2* 为几何体集合，则返回一个错误。

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

以下 SQL 检查两个多边形在几何上是否相等。

```
SELECT ST_Equals(ST_GeomFromText('POLYGON((0 2,1 1,0 -1,0 2))'), ST_GeomFromText('POLYGON((-1 3,2 1,0 -3,-1 3))'));
```

```
st_equals
-----------
 false
```

以下 SQL 检查两个线串在几何上是否相等。

```
SELECT ST_Equals(ST_GeomFromText('LINESTRING(1 0,10 0)'), ST_GeomFromText('LINESTRING(1 0,5 0,10 0)'));
```

```
st_equals
-----------
 true
```

# ST\$1ExteriorRing
<a name="ST_ExteriorRing-function"></a>

ST\$1ExteriorRing 返回一个表示输入面外环的闭合线串。返回的几何体的维度与输入几何体的维度相同。

## 语法
<a name="ST_ExteriorRing-function-syntax"></a>

```
ST_ExteriorRing(geom)
```

## 参数
<a name="ST_ExteriorRing-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_ExteriorRing-function-return"></a>

`GEOMETRY`子类型 的 `LINESTRING`。

返回的几何体的空间参考系统标识符 (SRID) 值是输入几何体的 SRID 值。

如果 *geom* 为 null，则返回 null。

如果 *geom* 不是多边形，则返回 null。

如果 *geom* 为空，则返回一个空的面。

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

以下 SQL 以闭合线串形式返回面的外环。

```
SELECT ST_AsEWKT(ST_ExteriorRing(ST_GeomFromText('POLYGON((7 9,8 7,11 6,15 8,16 6,17 7,17 10,18 12,17 14,15 15,11 15,10 13,9 12,7 9),(9 9,10 10,11 11,11 10,10 8,9 9),(12 14,15 14,13 11,12 14))')));
```

```
st_asewkt
-----------
 LINESTRING(7 9,8 7,11 6,15 8,16 6,17 7,17 10,18 12,17 14,15 15,11 15,10 13,9 12,7 9)
```

# ST\$1Force2D
<a name="ST_Force2D-function"></a>

ST\$1Force2D 返回输入几何体的 2D 几何体。对于 2D 几何体，将返回输入的副本。对于 3DZ、3DM 和 4D 几何体，ST\$1Force2D 将几何体投影到 xy 笛卡尔平面。输入几何体中的空点仍然是输出几何体中的空点。

## 语法
<a name="ST_Force2D-function-syntax"></a>

```
ST_Force2D(geom)
```

## 参数
<a name="ST_Force2D-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Force2D-function-return"></a>

`GEOMETRY`. 

返回的几何体的空间参考系统标识符 (SRID) 值是输入几何体的 SRID 值。

如果 *geom* 为 null，则返回 null。

如果 *geom* 为空，则返回一个空的几何体。

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

以下 SQL 从 3DZ 几何体返回 2D 几何体。

```
SELECT ST_AsEWKT(ST_Force2D(ST_GeomFromText('MULTIPOINT Z(0 1 2, EMPTY, 2 3 4, 5 6 7)')));
```

```
st_asewkt
-----------
  MULTIPOINT((0 1),EMPTY,(2 3),(5 6))
```

# ST\$1Force3D
<a name="ST_Force3D-function"></a>

ST\$1Force3D 是 ST\$1Force3DZ 的别名。有关更多信息，请参阅 [ST\$1Force3DZ](ST_Force3DZ-function.md)。

# ST\$1Force3DM
<a name="ST_Force3DM-function"></a>

ST\$1Force3DM 返回输入几何体的 3DM 几何体。对于 2D 几何体，输出几何体中非空点的 `m` 坐标全部设置为 `0`。对于 3DM 几何体，将返回输入几何体的副本。对于 3DZ 几何体，几何体将投影到 xy 笛卡尔平面，而输出几何体中的非空点的 `m` 坐标将全部设置为 `0`。对于 4D 几何体，几何体将投影到 xym 笛卡尔空间。输入几何体中的空点仍然是输出几何体中的空点。

## 语法
<a name="ST_Force3DM-function-syntax"></a>

```
ST_Force3DM(geom)
```

## 参数
<a name="ST_Force3DM-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Force3DM-function-return"></a>

`GEOMETRY`. 

返回的几何体的空间参考系统标识符 (SRID) 值是输入几何体的 SRID 值。

如果 *geom* 为 null，则返回 null。

如果 *geom* 为空，则返回一个空的几何体。

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

以下 SQL 从 3DZ 几何体中返回 3DM 几何体。

```
SELECT ST_AsEWKT(ST_Force3DM(ST_GeomFromText('MULTIPOINT Z(0 1 2, EMPTY, 2 3 4, 5 6 7)')));
```

```
st_asewkt
-----------
  MULTIPOINT M ((0 1 0),EMPTY,(2 3 0),(5 6 0))
```

# ST\$1Force3DZ
<a name="ST_Force3DZ-function"></a>

ST\$1Force3DZ 从输入几何体返回 3DZ 几何体。对于 2D 几何体，输出几何体中非空点的 `z` 坐标全部设置为 `0`。对于 3DM 几何体，几何体投影在 xy 笛卡尔平面上，输出几何体中非空点的 `z` 坐标全部设置为 `0`。对于 3DZ 几何体，将返回输入几何体的副本。对于 4D 几何体，几何体将投影到 xyz 笛卡尔空间。输入几何体中的空点仍然是输出几何体中的空点。

## 语法
<a name="ST_Force3DZ-function-syntax"></a>

```
ST_Force3DZ(geom)
```

## 参数
<a name="ST_Force3DZ-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Force3DZ-function-return"></a>

`GEOMETRY`. 

返回的几何体的空间参考系统标识符 (SRID) 值是输入几何体的 SRID 值。

如果 *geom* 为 null，则返回 null。

如果 *geom* 为空，则返回一个空的几何体。

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

以下 SQL 从 3DM 几何体返回 3DZ 几何体。

```
SELECT ST_AsEWKT(ST_Force3DZ(ST_GeomFromText('MULTIPOINT M(0 1 2, EMPTY, 2 3 4, 5 6 7)')));
```

```
st_asewkt
-----------
  MULTIPOINT Z ((0 1 0),EMPTY,(2 3 0),(5 6 0))
```

# ST\$1Force4D
<a name="ST_Force4D-function"></a>

ST\$1Force4D 返回输入几何体的 4D 几何体。对于 2D 几何体，输出几何体中非空点的 `z` 和 `m` 坐标全部设置为 `0`。对于 3DM 几何体，输出几何体中非空点的 `z` 坐标全部设置为 `0`。对于 3DZ 几何体，输出几何体中非空点的 `m` 坐标全部设置为 `0`。对于 4D 几何体，将返回输入几何体的副本。输入几何体中的空点仍然是输出几何体中的空点。

## 语法
<a name="ST_Force4D-function-syntax"></a>

```
ST_Force4D(geom)
```

## 参数
<a name="ST_Force4D-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Force4D-function-return"></a>

`GEOMETRY`. 

返回的几何体的空间参考系统标识符 (SRID) 值是输入几何体的 SRID 值。

如果 *geom* 为 null，则返回 null。

如果 *geom* 为空，则返回一个空的几何体。

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

以下 SQL 从 3DM 几何体返回 4D 几何体。

```
SELECT ST_AsEWKT(ST_Force4D(ST_GeomFromText('MULTIPOINT M(0 1 2, EMPTY, 2 3 4, 5 6 7)')));
```

```
st_asewkt
-----------
  MULTIPOINT ZM ((0 1 0 2),EMPTY,(2 3 0 4),(5 6 0 7))
```

# ST\$1GeoHash
<a name="ST_GeoHash-function"></a>

ST\$1GeoHash 以指定精度返回输入点的 `geohash` 表示形式。默认精度值为 20。有关 geohash 的定义的更多信息，请参阅维基百科中的 [Geohash](https://en.wikipedia.org/wiki/Geohash)。

## 语法
<a name="ST_GeoHash-function-syntax"></a>

```
ST_GeoHash(geom)
```

```
ST_GeoHash(geom, precision)
```

## 参数
<a name="ST_GeoHash-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *精度*   
一个 数据类型的 值`INTEGER` 默认值为 20。

## 返回类型
<a name="ST_GeoHash-function-return"></a>

`GEOMETRY`

该函数返回输入点的 `geohash` 表示形式。

如果输入点为空，该函数将返回 null。

如果输入几何体不是一个点，该函数将返回错误。

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

以下 SQL 返回输入点的 geohash 表示形式。

```
SELECT ST_GeoHash(ST_GeomFromText('POINT(45 -45)'), 25) AS geohash;
```

```
          geohash
---------------------------
 m000000000000000000000gzz
```

以下 SQL 返回 null，因为输入点为空。

```
SELECT ST_GeoHash(ST_GeomFromText('POINT EMPTY'), 10) IS NULL AS result;
```

```
 result
---------
 true
```

# ST\$1GeogFromText
<a name="ST_GeogFromText-function"></a>

ST\$1GeogFromText 从输入几何体的已知文本 (WKT) 或扩展的已知文本 (EWKT) 表示形式构造几何体对象。

## 语法
<a name="ST_GeogFromText-function-syntax"></a>

```
ST_GeogFromText(wkt_string)
```

## 参数
<a name="ST_GeogFromText-function-arguments"></a>

 *wkt\$1string*   
一个 `VARCHAR` 数据类型的值，它是地理的 WKT 或 EWKT 表示形式。

## 返回类型
<a name="ST_GeogFromText-function-return"></a>

`GEOGRAPHY`

如果 SRID 值已设置为输入中提供的值。如果未提供 SRID，则将其设置为 `4326`。

如果 *wkt\$1string* 为 null，则返回 null。

如果 *wkt\$1string* 无效，则返回一个错误。

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

以下 SQL 从地理对象构造一个具有 SRID 值的多边形。

```
SELECT ST_AsEWKT(ST_GeogFromText('SRID=4324;POLYGON((0 0,0 1,1 1,10 10,1 0,0 0))'));
```

```
  st_asewkt
------------------------------------------------
 SRID=4324;POLYGON((0 0,0 1,1 1,10 10,1 0,0 0))
```

以下 SQL 从地理对象构造一个多边形。将 SRID 值设置为 `4326`。

```
SELECT ST_AsEWKT(ST_GeogFromText('POLYGON((0 0,0 1,1 1,10 10,1 0,0 0))'));
```

```
 st_asewkt
------------------------------------------------
 SRID=4326;POLYGON((0 0,0 1,1 1,10 10,1 0,0 0))
```

# ST\$1GeogFromWKB
<a name="ST_GeogFromWKB-function"></a>

ST\$1GeogFromWKB 从输入地理的十六进制已知二进制 (WKB) 表示形式构造地理对象。

## 语法
<a name="ST_GeogFromWKB-function-syntax"></a>

```
ST_GeogFromWKB(wkb_string)
```

## 参数
<a name="ST_GeogFromWKB-function-arguments"></a>

 *wkb\$1string*   
一个 `VARCHAR` 数据类型的值，它是地理的十六进制 WKB 表示形式。

## 返回类型
<a name="ST_GeogFromWKB-function-return"></a>

`GEOGRAPHY`

如果提供了 SRID 值，则将其设置为所提供的值。如果未提供 SRID，则将其设置为 `4326`。

如果 *wkb\$1string* 为 null，则返回 null。

如果 *wkb\$1string* 无效，则返回一个错误。

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

以下 SQL 从十六进制 WKB 值构造了一个地理。

```
SELECT ST_AsEWKT(ST_GeogFromWKB('01030000000100000005000000000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000000000000000000000000000000000000000'));
```

```
 st_asewkt
------------------------------------------
 SRID=4326;POLYGON((0 0,0 1,1 1,1 0,0 0))
```

# ST\$1GeometryN
<a name="ST_GeometryN-function"></a>

ST\$1GeometryN 返回由输入几何体的输入索引指向的几何体，如下所示：
+ 当输入是点、线串或多边形时，如果索引等于一 (1)，则按原样返回几何体；如果索引不是一 (1)，则返回 null。
+ 如果输入是多点、多线串、多边形或几何体集合，则返回由输入索引指向的点、线串、多边形或几何体集合。

索引是从 1 开始的。结果的空间参考系统标识符 (SRID) 与输入几何体的相同。返回的几何体的维度与输入几何体的维度相同。

## 语法
<a name="ST_GeometryN-function-syntax"></a>

```
ST_GeometryN(geom, index)
```

## 参数
<a name="ST_GeometryN-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *index*   
一个 `INTEGER` 数据类型的值，表示从 1 开始的索引的位置。

## 返回类型
<a name="ST_GeometryN-function-return"></a>

`GEOMETRY` 

如果 *geom* 或 *index* 为 null，则返回 null。

如果 *index* 超出范围，则返回一个错误。

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

以下 SQL 返回几何体集合中的几何体。

```
WITH tmp1(idx) AS (SELECT 1 UNION SELECT 2),
tmp2(g) AS (SELECT ST_GeomFromText('GEOMETRYCOLLECTION(POLYGON((0 0,10 0,0 10,0 0)),LINESTRING(20 10,20 0,10 0))'))
SELECT idx, ST_AsEWKT(ST_GeometryN(g, idx)) FROM tmp1, tmp2 ORDER BY idx;
```

```
 idx |          st_asewkt           
-----+------------------------------
   1 | POLYGON((0 0,10 0,0 10,0 0))
   2 | LINESTRING(20 10,20 0,10 0)
```

# ST\$1GeometryType
<a name="ST_GeometryType-function"></a>

ST\$1GeometryType 以字符串形式返回输入几何体的子类型。

对于 3DM、3DZ 和 4D 几何体输入，ST\$1GeometryType 返回的结果与 2D 几何体输入的结果相同。

## 语法
<a name="ST_GeometryType-function-syntax"></a>

```
ST_GeometryType(geom)
```

## 参数
<a name="ST_GeometryType-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_GeometryType-function-return"></a>

`VARCHAR`，表示 *geom* 的子类型。

如果 *geom* 为 null，则返回 null。

返回的值如下所示。


| 返回的字符串值 | 几何体子类型 | 
| --- | --- | 
| `ST_Point` | 在 *geom* 为 `POINT` 子类型时返回  | 
| `ST_LineString` | 在 *geom* 为 `LINESTRING` 子类型时返回  | 
| `ST_Polygon` | 在 *geom* 为 `POLYGON` 子类型时返回  | 
| `ST_MultiPoint` | 在 *geom* 为 `MULTIPOINT` 子类型时返回  | 
| `ST_MultiLineString` | 在 *geom* 为 `MULTILINESTRING` 子类型时返回  | 
| `ST_MultiPolygon` | 在 *geom* 为 `MULTIPOLYGON` 子类型时返回  | 
| `ST_GeometryCollection` | 在 *geom* 为 `GEOMETRYCOLLECTION` 子类型时返回  | 

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

以下 SQL 返回输入线串几何体的子类型。

```
SELECT ST_GeometryType(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'));
```

```
st_geometrytype
-------------
 ST_LineString
```

# ST\$1GeomFromEWKB
<a name="ST_GeomFromEWKB-function"></a>

ST\$1GeomFromEWKB 从输入几何体的扩展的已知二进制 (EWKB) 表示形式构造几何体对象。

ST\$1GeomFromEWKB 接受以 WKB 和 EWKB 十六进制格式编写的 3DZ、3DM 和 4D 几何体。

## 语法
<a name="ST_GeomFromEWKB-function-syntax"></a>

```
ST_GeomFromEWKB(ewkb_string)
```

## 参数
<a name="ST_GeomFromEWKB-function-arguments"></a>

 *ewkb\$1string*   
一个 `VARCHAR` 数据类型的值，它是几何体的十六进制 EWKB 表示形式。

## 返回类型
<a name="ST_GeomFromEWKB-function-return"></a>

`GEOMETRY`

如果 *ewkb\$1string* 为 null，则返回 null。

如果 *ewkb\$1string* 无效，则返回一个错误。

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

以下 SQL 从一个 EWKB 值构造一个多边形，并返回一个多边形的 EWKT 表示形式。

```
SELECT ST_AsEWKT(ST_GeomFromEWKB('0103000020E61000000100000005000000000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000000000000000000000000000000000000000'));
```

```
 st_asewkt
--------------------------------
 SRID=4326;POLYGON((0 0,0 1,1 1,1 0,0 0))
```

# ST\$1GeomFromEWKT
<a name="ST_GeomFromEWKT-function"></a>

ST\$1GeomFromEWKT 从输入几何体的扩展的已知文本 (EWKT) 表示形式构造几何体对象。

ST\$1GeomFromEWKT 接受 3DZ、3DM 和 4D，其中几何类型分别以 Z、M 或 ZM 作为前缀。

## 语法
<a name="ST_GeomFromEWKT-function-syntax"></a>

```
ST_GeomFromEWKT(ewkt_string)
```

## 参数
<a name="ST_GeomFromEWKT-function-arguments"></a>

 *ewkt\$1string*   
数据类型 `VARCHAR` 的或计算结果为 `VARCHAR` 类型的表达式，即几何体的 EWKT 表示形式。  
您可以使用 WKT 关键字 `EMPTY` 指定一个空点、一个带有空点的多点或一个带有空点的几何体集合。以下示例将创建空点。  

```
ST_GeomFromEWKT('SRID=4326;POINT EMPTY');
```

## 返回类型
<a name="ST_GeomFromEWKT-function-return"></a>

`GEOMETRY`

如果 *ewkt\$1string* 为 null，则返回 null。

如果 *ewkt\$1string* 无效，则返回一个错误。

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

以下 SQL 通过 EWKT 值构造多线串并返回几何体。它还返回几何体的 ST\$1AsEWKT 结果。

```
SELECT ST_GeomFromEWKT('SRID=4326;MULTILINESTRING((1 0,1 0),(2 0,3 0),(4 0,5 0,6 0))') as geom, ST_AsEWKT(geom);
```

```
                                                                                                                                                       geom                                                                                                                                                       |                          st_asewkt                           
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------
 0105000020E610000003000000010200000002000000000000000000F03F0000000000000000000000000000F03F00000000000000000102000000020000000000000000000040000000000000000000000000000008400000000000000000010200000003000000000000000000104000000000000000000000000000001440000000000000000000000000000018400000000000000000 | SRID=4326;MULTILINESTRING((1 0,1 0),(2 0,3 0),(4 0,5 0,6 0))
```

# ST\$1GeomFromGeoHash
<a name="ST_GeomFromGeoHash-function"></a>

ST\$1GeomFromGeoHash 从输入几何体的 geohash 表示形式构造几何体对象。ST\$1GeomFromGeoHash 返回空间参考标识符 (SRID) 为零 (0) 的二维 (2D) 几何体。有关 geohash 格式的更多信息，请参阅 Wikipedia 中的 [Geohash](https://en.wikipedia.org/wiki/Geohash)。

## 语法
<a name="ST_GeomFromGeoHash-function-syntax"></a>

```
ST_GeomFromGeoHash(geohash_string)
```

```
ST_GeomFromGeoHash(geohash_string, precision)
```

## 参数
<a name="ST_GeomFromGeoHash-function-arguments"></a>

 *geohash\$1string*   
数据类型为 `VARCHAR` 的值或计算结果为 `VARCHAR` 类型的表达式，即几何体的 geohash 表示形式。

 *精度*   
数据类型 `INTEGER` 的值，表示 geohash 的精度。该值是要用作精度的 geohash 的字符数。如果未指定该值、值小于零或大于 *geohash\$1string* 长度，则使用 *geohash\$1string* 长度。

## 返回类型
<a name="ST_GeomFromGeoHash-function-return"></a>

`GEOMETRY`

如果 *geohash\$1string* 为 null，则返回 null。

如果 *geohash\$1string* 无效，则返回一个错误。

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

以下 SQL 返回具有高精度的多边形。

```
SELECT ST_AsText(ST_GeomFromGeoHash('9qqj7nmxncgyy4d0dbxqz0'));
```

```
 st_asewkt       
-----------------------
 POLYGON((-115.172816 36.114646,-115.172816 36.114646,-115.172816 36.114646,-115.172816 36.114646,-115.172816 36.114646))
```

以下 SQL 返回具有高精度的点。

```
SELECT ST_AsText(ST_GeomFromGeoHash('9qqj7nmxncgyy4d0dbxqz00'));
```

```
 st_asewkt       
-----------------------
 POINT(-115.172816 36.114646)
```

以下 SQL 返回具有低精度的多边形。

```
SELECT ST_AsText(ST_GeomFromGeoHash('9qq'));
```

```
 st_asewkt       
-----------------------
 POLYGON((-115.3125 35.15625,-115.3125 36.5625,-113.90625 36.5625,-113.90625 35.15625,-115.3125 35.15625))
```

以下 SQL 返回精度为 3 的多边形。

```
SELECT ST_AsText(ST_GeomFromGeoHash('9qqj7nmxncgyy4d0dbxqz0', 3));
```

```
 st_asewkt       
-----------------------
 POLYGON((-115.3125 35.15625,-115.3125 36.5625,-113.90625 36.5625,-113.90625 35.15625,-115.3125 35.15625))
```

# ST\$1GeomFromGeoJSON
<a name="ST_GeomFromGeoJSON-function"></a>

ST\$1GeomFromGeoJSON 从输入几何体的 GeoJSON 表示形式构造几何体对象。有关 GeoJSON 格式的更多信息，请参阅 Wikipedia 中的 [GeoJSON](https://en.wikipedia.org/wiki/GeoJSON)。

如果至少有一个点具有三个或更多坐标，则生成的几何体为 3DZ，其中只有两个坐标的点的 Z 分量为零。如果输入 GeoJSON 中的所有点都包含两个坐标或为空，则 ST\$1GeomFromGeoJSON 将返回 2D 几何体。返回的几何体的空间参考标识符 (SRID) 始终为 4326。

## 语法
<a name="ST_GeomFromGeoJSON-function-syntax"></a>

```
ST_GeomFromGeoJSON(geojson_string)
```

## 参数
<a name="ST_GeomFromGeoJSON-function-arguments"></a>

 *geojson\$1string*   
数据类型为 `VARCHAR` 或 `SUPER` 的值或计算结果为 `VARCHAR` 类型的表达式，即几何体的 GeoJSON 表示形式。

## 返回类型
<a name="ST_GeomFromGeoJSON-function-return"></a>

`GEOMETRY`

如果 *geojson\$1string* 为 null，则返回 null。

如果 *geojson\$1string* 无效，则返回一个错误。

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

以下 SQL 返回以输入 GeoJSON 表示的 2D 几何体。

```
SELECT ST_AsEWKT(ST_GeomFromGeoJSON('{"type":"Point","coordinates":[1,2]}'));
```

```
 st_asewkt       
-----------------------
 SRID=4326;POINT(1 2)
```

以下 SQL 返回以输入 GeoJSON 表示的 3DZ 几何体。

```
SELECT ST_AsEWKT(ST_GeomFromGeoJSON('{"type":"LineString","coordinates":[[1,2,3],[4,5,6],[7,8,9]]}'));
```

```
 st_asewkt  
------------------------------------------
 SRID=4326;LINESTRING Z (1 2 3,4 5 6,7 8 9)
```

当输入 GeoJSON 中只有一个点具有三个坐标，而所有其他点具有两个坐标时，以下 SQL 返回 3DZ 几何体。

```
SELECT ST_AsEWKT(ST_GeomFromGeoJSON('{"type":"Polygon","coordinates":[[[0, 0],[0, 1, 8],[1, 0],[0, 0]]]}'));
```

```
 st_asewkt  
------------------------------------------------
 SRID=4326;POLYGON Z ((0 0 0,0 1 8,1 0 0,0 0 0))
```

# ST\$1GeomFromGeoSquare
<a name="ST_GeomFromGeoSquare-function"></a>

ST\$1GeomFromGeoSquare 返回一个几何体，该几何体覆盖由输入 geosquare 值表示的区域。返回的几何体始终是二维的。要计算 geosquare 值，请参阅 [ST\$1GeoSquare](ST_GeoSquare-function.md)。

## 语法
<a name="ST_GeomFromGeoSquare-function-syntax"></a>

```
ST_GeomFromGeoSquare(geosquare)
```

```
ST_GeomFromGeoSquare(geosquare, max_depth)
```

## 参数
<a name="ST_GeomFromGeoSquare-function-arguments"></a>

 *geosquare*   
一个数据类型为 `BIGINT` 的值或一个计算结果为 `BIGINT` 类型的 geosquare 值的表达式，该值描述了为达到目标正方形，而在初始域上进行细分的顺序。此值由 [ST\$1GeoSquare](ST_GeoSquare-function.md) 计算。

 *max\$1depth*   
一个数据类型为 `INTEGER` 的值，表示在初始域上进行的最大域细分次数。此值必须等于或大于 `1`。

## 返回类型
<a name="ST_GeomFromGeoSquare-function-return"></a>

`GEOMETRY`

如果 *geosquare* 无效，则该函数会返回错误。

如果输入 *max\$1depth* 不在范围内，则该函数会返回错误。

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

以下 SQL 从 geosquare 值返回几何体。

```
SELECT ST_AsText(ST_GeomFromGeoSquare(797852));
```

```
 st_astext       
--------------------------------------------------------------------------------------------------------------------
 POLYGON((13.359375 52.3828125,13.359375 52.734375,13.7109375 52.734375,13.7109375 52.3828125,13.359375 52.3828125))
```

以下 SQL 从 geosquare 值返回几何体，最大深度为 `3`。

```
SELECT ST_AsText(ST_GeomFromGeoSquare(797852, 3));
```

```
 st_astext       
--------------------------------------
 POLYGON((0 45,0 90,45 90,45 45,0 45))
```

以下 SQL 首先通过将 x 坐标指定为经度，将 y 坐标指定为纬度 (-122.3, 47.6) 来计算西雅图的 geosquare 值，然后为 geosquare 返回多边形。尽管输出是二维几何体，但它可用于根据经度和纬度计算空间数据。

```
SELECT ST_AsText(ST_GeomFromGeoSquare(ST_GeoSquare(ST_Point(-122.3, 47.6))));
```

```
 st_astext
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
POLYGON((-122.335167014971 47.6080129947513,-122.335167014971 47.6080130785704,-122.335166931152 47.6080130785704,-122.335166931152 47.6080129947513,-122.335167014971 47.6080129947513))
```

# ST\$1GeomFromText
<a name="ST_GeomFromText-function"></a>

ST\$1GeomFromText 从输入几何体的已知文本 (WKT) 表示形式构造几何体对象。

ST\$1GeomFromText 接受 3DZ、3DM 和 4D，其中几何类型分别以 Z、M 或 ZM 作为前缀。

## 语法
<a name="ST_GeomFromText-function-syntax"></a>

```
ST_GeomFromText(wkt_string)
```

```
ST_GeomFromText(wkt_string, srid)
```

## 参数
<a name="ST_GeomFromText-function-arguments"></a>

 *wkt\$1string*   
一个 `VARCHAR` 数据类型的值，它是几何体的 WKT 表示形式。  
您可以使用 WKT 关键字 `EMPTY` 指定一个空点、一个带有空点的多点或一个带有空点的几何体集合。以下示例创建一个多点，其中包括一个空点和一个非空点。  

```
ST_GeomFromEWKT('MULTIPOINT(1 0,EMPTY)');
```

 *srid*   
一个 `INTEGER` 数据类型的值，它是空间参考标识符 (SRID)。如果提供了一个 SRID 值，则返回的几何体将具有此 SRID 值。否则，返回的几何体的 SRID 值将设置为零 (0)。

## 返回类型
<a name="ST_GeomFromText-function-return"></a>

`GEOMETRY`

如果 *wkt\$1string* 或 *srid* 为 null，则返回 null。

如果 *srid* 为负，则返回 null。

如果 *wkt\$1string* 无效，则返回一个错误。

如果 *srid* 无效，则返回一个错误。

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

以下 SQL 从 WKT 表示形式和 SRID 值构造几何体对象。

```
SELECT ST_GeomFromText('POLYGON((0 0,0 1,1 1,1 0,0 0))',4326);
```

```
st_geomfromtext
--------------------------------
0103000020E61000000100000005000000000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000000000000000000000000000000000000000
```

# ST\$1GeomFromWKB
<a name="ST_GeomFromWKB-function"></a>

ST\$1GeomFromWKB 从输入几何体的十六进制已知二进制 (WKB) 表示形式构造几何体对象。

ST\$1GeomFromWKB 接受以 WKB 十六进制格式编写的 3DZ、3DM 和 4D 几何体。

## 语法
<a name="ST_GeomFromWKB-function-syntax"></a>

```
ST_GeomFromWKB(wkb_string)
```

```
ST_GeomFromWKB(wkb_string, srid)
```

## 参数
<a name="ST_GeomFromWKB-function-arguments"></a>

 *wkb\$1string*   
一个 `VARCHAR` 数据类型的值，它是几何体的十六进制 WKB 表示形式。

 *srid*   
一个 `INTEGER` 数据类型的值，它是空间参考标识符 (SRID)。如果提供了一个 SRID 值，则返回的几何体将具有此 SRID 值。否则，返回的几何体的 SRID 值将设置为 0。

## 返回类型
<a name="ST_GeomFromWKB-function-return"></a>

`GEOMETRY`

如果 *wkb\$1string* 或 *srid* 为 null，则返回 null。

如果 *srid* 为负，则返回 null。

如果 *wkb\$1string* 无效，则返回一个错误。

如果 *srid* 无效，则返回一个错误。

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

以下 SQL 从一个 WKB 值构造一个多边形，并返回一个多边形的 WKT 表示形式。

```
SELECT ST_AsText(ST_GeomFromWKB('01030000000100000005000000000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000000000000000000000000000000000000000'));            
```

```
 st_astext
--------------------------------
 POLYGON((0 0,0 1,1 1,1 0,0 0))
```

# ST\$1GeoSquare
<a name="ST_GeoSquare-function"></a>

ST\$1GeoSquare 以递归方式将域 ([-180, 180], [-90, 90]) 细分为相等的正方形区域，称为 *geosquare*，直至指定深度。细分基于所提供的一个点的位置。包含该点的 geosquare 在每一步都被细分，直至达到最大深度。这个 geosquare 的选择是稳定的，即，该函数的结果仅取决于输入参数。该函数将返回一个唯一值，用于标识该点所在的最终 geosquare。

ST\$1GeoSquare 接受一个 POINT 值，其 x 坐标表示经度，y 坐标表示纬度。经度和纬度分别限制为 [-180, 180] 和 [-90, 90]。ST\$1GeoSquare 的输出可以用作 [ST\$1GeomFromGeoSquare](ST_GeomFromGeoSquare-function.md) 函数的输入。

地球沿赤道一周的弧线是 360°，且地球被分为两个半球（东半球和西半球），每个半球的经线（子午线）都是从 0°到 180°。按照惯例，投影到笛卡尔平面上的 x 轴时，东经线为“\$1”（正）坐标，西经线为“-”（负）坐标。在地球的 0°赤道线以北和以南分别有 90°纬线，每条纬线都与地球的 0°赤道线平行。按照惯例，投影到笛卡尔平面时，北纬线与“\$1”（正）y 轴相交，南纬线与“-”（负）y 轴相交。由经线和纬线相交形成的球形网格被转换为投影到笛卡尔平面上的网格，在笛卡尔平面上具有标准的正负 x 坐标和正负 y 坐标。

ST\$1GeoSquare 的目的是用相等的代码值标记相近的点。位于同一 geosquare 中的点将获得相同的代码值。geosquare 用于将地理坐标（纬度和经度）编码为整数。较大的区域被划分为网格，以在地图上以不同的分辨率描绘一个区域。geosquare 可用于空间索引、空间分组、邻近搜索、位置搜索和创建唯一的地点标识符。[ST\$1GeoHash](ST_GeoHash-function.md) 函数遵循类似的过程，将区域划分为网格，但编码不同。

## 语法
<a name="ST_GeoSquare-function-syntax"></a>

```
ST_GeoSquare(geom)
```

```
ST_GeoSquare(geom, max_depth)
```

## 参数
<a name="ST_ST_GeoSquare-function-arguments"></a>

 *geom*   
一个数据类型为 `GEOMETRY` 的 POINT 值，或一个计算结果为 POINT 子类型的表达式。该点的 x 坐标（经度）必须在以下范围内：`-180` – `180`。该点的 y 坐标（纬度）必须在以下范围内：`-90` – `90`。

 *max\$1depth*   
数据类型 `INTEGER` 的值。包含该点的域被以递归方式细分的最大次数。该值必须是介于 1 到 32 之间的整数。默认值为 32。细分的实际最终次数小于或等于指定的 *max\$1depth*。

## 返回类型
<a name="ST_GeoSquare-function-return"></a>

`BIGINT`

该函数返回一个唯一值，用于标识输入点所在的最终 geosquare。

如果输入 *geom* 不是点，则该函数将返回错误。

如果输入点为空，则返回值不是 [ST\$1GeomFromGeoSquare](ST_GeomFromGeoSquare-function.md) 函数的有效输入。使用 [ST\$1IsEmpty](ST_IsEmpty-function.md) 函数可防止使用空点调用 ST\$1GeoSquare。

如果输入点不在范围内，则该函数将返回错误。

如果输入 *max\$1depth* 超出范围，则该函数将返回错误。

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

以下 SQL 从输入点返回 geosquare。

```
SELECT ST_GeoSquare(ST_Point(13.5, 52.5));
```

```
  st_geosquare
-----------------------
 -4410772491521635895
```

以下 SQL 从输入点返回 geosquare，最大深度为 `10`。

```
SELECT ST_GeoSquare(ST_Point(13.5, 52.5), 10);
```

```
 st_geosquare
--------------
 797852
```

# ST\$1InteriorRingN
<a name="ST_InteriorRingN-function"></a>

ST\$1InteriorRingN 返回与索引位置处输入面的内环相对应的闭合线串。返回的几何体的维度与输入几何体的维度相同。

## 语法
<a name="ST_InteriorRingN-function-syntax"></a>

```
ST_InteriorRingN(geom, index)
```

## 参数
<a name="ST_InteriorRingN-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *index*   
一个 `INTEGER` 数据类型的值，表示从 1 开始的索引环的位置。

## 返回类型
<a name="ST_InteriorRingN-function-return"></a>

`GEOMETRY`子类型 的 `LINESTRING`。

返回的几何体的空间参考系统标识符 (SRID) 值是输入几何体的 SRID 值。

如果 *geom* 或 *index* 为 null，则返回 null。

如果 *index* 超出范围，则返回 null。

如果 *geom* 不是多边形，则返回 null。

如果 *geom* 为空面，则返回 null。

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

以下 SQL 以闭合线串形式返回面的第二个环。

```
SELECT ST_AsEWKT(ST_InteriorRingN(ST_GeomFromText('POLYGON((7 9,8 7,11 6,15 8,16 6,17 7,17 10,18 12,17 14,15 15,11 15,10 13,9 12,7 9),(9 9,10 10,11 11,11 10,10 8,9 9),(12 14,15 14,13 11,12 14))'),2));
```

```
st_asewkt
-----------
 LINESTRING(12 14,15 14,13 11,12 14)
```

# ST\$1Intersects
<a name="ST_Intersects-function"></a>

如果两个输入几何体的 2D 投影至少有一个共同点，则 ST\$1Intersects 返回 true。

## 语法
<a name="ST_Intersects-function-syntax"></a>

```
ST_Intersects(geom1, geom2)
```

## 参数
<a name="ST_Intersects-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Intersects-function-return"></a>

`BOOLEAN`

如果 *geom1* 或 *geom2* 为 null，则返回 null。

如果 *geom1* 和 *geom2* 不具有相同的空间参考系统标识符 (SRID) 值，则返回一个错误。

如果 *geom1* 或 *geom2* 为几何体集合，则返回一个错误。

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

以下 SQL 检查第一个多边形是否与第二个多边形相交。

```
SELECT ST_Intersects(ST_GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),(2 2,2 5,5 5,5 2,2 2))'), ST_GeomFromText('MULTIPOINT((4 4),(6 6))'));
```

```
st_intersects              
-------------
 true
```

# ST\$1Intersection
<a name="ST_Intersection-function"></a>

ST\$1Interction 返回一个表示两个几何体的点集交集的几何体。也就是说，它返回两个输入几何体间共享的部分。

## 语法
<a name="ST_Intersection-function-syntax"></a>

```
ST_Intersection(geom1, geom2)
```

## 参数
<a name="ST_Intersection-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Intersection-function-return"></a>

`GEOMETRY`

如果 *geom1* 和 *geom2* 不共享任何空间（它们不相交），则返回一个空的几何体。

如果 *geom1* 或 *geom2* 为空，则返回一个空的几何体。

如果 *geom1* 和 *geom2* 不具有相同的空间参考系统标识符 (SRID) 值，则返回一个错误。

如果 *geom1* 或 *geom2* 为几何体集合，则返回一个错误。

如果 *geom1* 或 *geom2* 非二维 (2D) 几何体，则返回一个错误。

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

以下 SQL 返回表示两个输入几何体交集的非空几何体。

```
SELECT ST_AsEWKT(ST_Intersection(ST_GeomFromText('polygon((0 0,100 100,0 200,0 0))'), ST_GeomFromText('polygon((0 0,10 0,0 10,0 0))')));
```

```
        st_asewkt        
-------------------------
 POLYGON((0 0,0 10,5 5,0 0))
```

传递不相交（无交集）输入几何体时，以下 SQL 返回一个空几何体。

```
SELECT ST_AsEWKT(ST_Intersection(ST_GeomFromText('linestring(0 100,0 0)'), ST_GeomFromText('polygon((1 0,10 0,1 10,1 0))')));
```

```
    st_asewkt     
------------------
 LINESTRING EMPTY
```

# ST\$1IsPolygonCCW
<a name="ST_IsPolygonCCW-function"></a>

如果输入面或多面的 2D 投影是逆时针方向，则 ST\$1IsPolygonCCW 返回 true。如果输入几何体是点、线串、多点或多线串，则返回 true。对于几何体集合，如果集合中的所有几何体都是逆时针方向，则 ST\$1IsPolygonCCW 返回 true。

## 语法
<a name="ST_IsPolygonCCW-function-syntax"></a>

```
ST_IsPolygonCCW(geom)
```

## 参数
<a name="ST_IsPolygonCCW-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_IsPolygonCCW-function-return"></a>

`BOOLEAN`

如果 *geom* 为 null，则返回 null。

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

以下 SQL 检查面是否为逆时针方向。

```
SELECT ST_IsPolygonCCW(ST_GeomFromText('POLYGON((7 9,8 7,11 6,15 8,16 6,17 7,17 10,18 12,17 14,15 15,11 15,10 13,9 12,7 9),(9 9,10 10,11 11,11 10,10 8,9 9),(12 14,15 14,13 11,12 14))'));
```

```
 st_ispolygonccw
----------
 true
```

# ST\$1IsPolygonCW
<a name="ST_IsPolygonCW-function"></a>

如果输入面或多面的 2D 投影是顺时针方向，则 ST\$1IsPolygonCW 会返回 true。如果输入几何体是点、线串、多点或多线串，则返回 true。对于几何体集合，如果集合中的所有几何体都是顺时针方向，则 ST\$1IsPolygonCW 返回 true。

## 语法
<a name="ST_IsPolygonCW-function-syntax"></a>

```
ST_IsPolygonCW(geom)
```

## 参数
<a name="ST_IsPolygonCW-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_IsPolygonCW-function-return"></a>

`BOOLEAN`

如果 *geom* 为 null，则返回 null。

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

以下 SQL 检查面是否为顺时针方向。

```
SELECT ST_IsPolygonCW(ST_GeomFromText('POLYGON((7 9,8 7,11 6,15 8,16 6,17 7,17 10,18 12,17 14,15 15,11 15,10 13,9 12,7 9),(9 9,10 10,11 11,11 10,10 8,9 9),(12 14,15 14,13 11,12 14))'));
```

```
 st_ispolygonccw
----------
 true
```

# ST\$1IsClosed
<a name="ST_IsClosed-function"></a>

如果输入几何体的 2D 投影已闭合，则 ST\$1IsClosed 返回 true。以下规则定义闭合的几何体：
+ 输入的几何体是一个点或一个多点。
+ 输入几何体是一个线串，并且该线串的起点和终点是重合的。
+ 输入几何体是一个非空的多线串，并且其所有线串均已闭合。
+ 输入几何体是一个非空多边形，所有多边形的环都是非空的，并且所有环的起点和终点都是重合的。
+ 输入几何体是一个非空的多边形集合，并且其所有多边形均已闭合。
+ 输入几何体是一个非空几何体集合，并且其所有组件均已闭合。

## 语法
<a name="ST_IsClosed-function-syntax"></a>

```
ST_IsClosed(geom)
```

## 参数
<a name="ST_IsClosed-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_IsClosed-function-return"></a>

`BOOLEAN`

如果 *geom* 是一个空点，则返回 false。

如果 *geom* 为 null，则返回 null。

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

以下 SQL 检查多边形是否已闭合。

```
SELECT ST_IsClosed(ST_GeomFromText('POLYGON((0 2,1 1,0 -1,0 2))'));
```

```
st_isclosed
-----------
 true
```

# ST\$1IsCollection
<a name="ST_IsCollection-function"></a>

如果输入几何体为下列子类型之一，则 ST\$1IsCollection 返回 true：`GEOMETRYCOLLECTION`、`MULTIPOINT`、`MULTILINESTRING` 或 `MULTIPOLYGON`。

## 语法
<a name="ST_IsCollection-function-syntax"></a>

```
ST_IsCollection(geom)
```

## 参数
<a name="ST_IsCollection-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_IsCollection-function-return"></a>

`BOOLEAN`

如果 *geom* 为 null，则返回 null。

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

以下 SQL 检查多边形是否为一个集合。

```
SELECT ST_IsCollection(ST_GeomFromText('POLYGON((0 2,1 1,0 -1,0 2))'));
```

```
st_iscollection
-----------
 false
```

# ST\$1IsEmpty
<a name="ST_IsEmpty-function"></a>

如果输入几何体是空的，则 ST\$1IsEmpty 返回 true。如果几何体至少包含一个非空点，则该几何体不为空。

如果输入几何体至少有一个非空点，ST\$1IsEmpty 返回 true。

## 语法
<a name="ST_IsEmpty-function-syntax"></a>

```
ST_IsEmpty(geom)
```

## 参数
<a name="ST_IsEmpty-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_IsEmpty-function-return"></a>

`BOOLEAN`

如果 *geom* 为 null，则返回 null。

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

以下 SQL 检查指定的多边形是否为空。

```
SELECT ST_IsEmpty(ST_GeomFromText('POLYGON((0 2,1 1,0 -1,0 2))'));
```

```
st_isempty
-----------
 false
```

# ST\$1IsRing
<a name="ST_IsRing-function"></a>

如果输入线串为环形，则 ST\$1IsRing 返回 true。如果线串闭合且简单，则为环形。

## 语法
<a name="ST_IsRing-function-syntax"></a>

```
ST_IsRing(geom)
```

## 参数
<a name="ST_IsRing-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。几何体必须是 `LINESTRING`。

## 返回类型
<a name="ST_IsRing-function-return"></a>

`BOOLEAN`

如果 *geom* 不是 `LINESTRING`，则返回一个错误。

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

以下 SQL 检查指定的线串是否为环形。

```
SELECT ST_IsRing(ST_GeomFromText('linestring(0 0, 1 1, 1 2, 0 0)'));
```

```
st_isring
-----------
 true
```

# ST\$1IsSimple
<a name="ST_IsSimple-function"></a>

如果输入几何体的 2D 投影很简单，则 ST\$1IsSimple 返回 true。有关简单几何体的定义的更多信息，请参阅[几何简单性](spatial-terminology.md#spatial-terminology-simplicity)。

## 语法
<a name="ST_IsSimple-function-syntax"></a>

```
ST_IsSimple(geom)
```

## 参数
<a name="ST_IsSimple-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_IsSimple-function-return"></a>

`BOOLEAN`

如果 *geom* 为 null，则返回 null。

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

以下 SQL 检查指定的线串是否简单。在本例中，它并不简单，因为它具有自交集。

```
SELECT ST_IsSimple(ST_GeomFromText('LINESTRING(0 0,10 0,5 5,5 -5)'));
```

```
 st_issimple
-----------
 false
```

# ST\$1IsValid
<a name="ST_IsValid-function"></a>

如果输入几何体的 2D 投影有效，ST\$1IsValid 返回 true。有关有效几何体的定义的更多信息，请参阅[几何有效性](spatial-terminology.md#spatial-terminology-validity)。

## 语法
<a name="ST_IsValid-function-syntax"></a>

```
ST_IsValid(geom)
```

## 参数
<a name="ST_IsValid-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_IsValid-function-return"></a>

`BOOLEAN`

如果 *geom* 为 null，则返回 null。

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

以下 SQL 检查指定的面是否有效。在此示例中，面无效，因为面的内部并非简单地连接。

```
SELECT ST_IsValid(ST_GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),(5 0,10 5,5 10,0 5,5 0))'));
```

```
 st_isvalid
-----------
 false
```

# ST\$1Length
<a name="ST_Length-function"></a>

对于线性几何体，ST\$1Length 返回 2D 投影的笛卡尔长度。长度单位与用于表示输入几何体坐标的单位相同。对于点、多点和平面几何体，此函数返回零 (0)。当输入为几何体集合时，此函数返回集合中的几何体长度之和。

对于地理，ST\$1Length 返回由 SRID 确定的在椭球体上计算的输入线性地理的 2D 投影的测地线长度。长度以米为单位。对于点、多点和平面地理，此函数返回零 (0)。当输入为几何体集合时，此函数返回集合中的地理长度之和。

## 语法
<a name="ST_Length-function-syntax"></a>

```
ST_Length(geo)
```

## 参数
<a name="ST_Length-function-arguments"></a>

 *geo*   
一个 `GEOMETRY` 或 `GEOGRAPHY` 数据类型的值，或一个计算结果为 `GEOMETRY` 或 `GEOGRAPHY` 类型的表达式。

## 返回类型
<a name="ST_Length-function-return"></a>

`DOUBLE PRECISION`

如果 *geo* 为 null，则返回 null。

如果找不到 SRID 值，则返回一个错误。

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

以下 SQL 返回多线串的笛卡尔长度。

```
SELECT ST_Length(ST_GeomFromText('MULTILINESTRING((0 0,10 0,0 10),(10 0,20 0,20 10))'));
```

```
st_length
--------------------------------
  44.142135623731
```

以下 SQL 返回几何体中线串的长度。

```
SELECT ST_Length(ST_GeogFromText('SRID=4326;LINESTRING(5 0,6 0,4 0)'));
```

```
 st_length 
------------------
 333958.472379804
```

以下 SQL 返回几何体中点的长度。

```
SELECT ST_Length(ST_GeogFromText('SRID=4326;POINT(4 5)'));
```

```
 st_length 
-----------
 0
```

# ST\$1LengthSphere
<a name="ST_LengthSphere-function"></a>

ST\$1LengthSphere 返回线性几何体的长度（以米为单位）。对于点、多点和平面几何体，ST\$1LengthSphere 返回 0。对于几何体集合，ST\$1LengthSphere 将返回集合中线性几何体的总长度（以米为单位）。

ST\$1LengthSphere 将输入几何体的每个点的坐标解释为经度和纬度（以度为单位）。对于 3DZ、3DM 或 4D 几何体，仅使用前两个坐标。

## 语法
<a name="ST_LengthSphere-function-syntax"></a>

```
ST_LengthSphere(geom)
```

## 参数
<a name="ST_LengthSphere-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_LengthSphere-function-return"></a>

`DOUBLE PRECISION` 长度（以米为单位）。长度计算基于地球的球状模型，其半径为地球世界大地测量系统 (WGS) 84 椭球模型的地球平均半径。

如果 *geom* 为 null，则返回 null。

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

以下示例 SQL 计算线串的长度（以米为单位）。

```
SELECT ST_LengthSphere(ST_GeomFromText('LINESTRING(10 10,45 45)'));
```

```
 st_lengthsphere  
------------------
 5127736.08292556
```

# ST\$1Length2D
<a name="ST_Length2D-function"></a>

ST\$1Length2D 是 ST\$1Length 的别名。有关更多信息，请参阅 [ST\$1Length](ST_Length-function.md)。

# ST\$1LineFromMultiPoint
<a name="ST_LineFromMultiPoint-function"></a>

ST\$1LineFromMultiPoint 返回输入多点几何体中的线串。点的顺序将保留。返回的几何体的空间参考系统标识符 (SRID) 与输入几何体的相同。返回的几何体的维度与输入几何体的维度相同。

## 语法
<a name="ST_LineFromMultiPoint-function-syntax"></a>

```
ST_LineFromMultiPoint(geom)
```

## 参数
<a name="ST_LineFromMultiPoint-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `MULTIPOINT`。

## 返回类型
<a name="ST_LineFromMultiPoint-function-return"></a>

`GEOMETRY`

如果 *geom* 为 null，则返回 null。

如果 *geom* 为空，则返回空的 `LINESTRING`。

如果 *geom* 包含空点，则忽略这些空点。

如果 *geom* 不是 `MULTIPOINT`，则返回错误。

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

以下 SQL 从多点创建线串。

```
SELECT ST_AsEWKT(ST_LineFromMultiPoint(ST_GeomFromText('MULTIPOINT(0 0,10 0,10 10,5 5,0 5)',4326)));
```

```
 st_asewkt
---------------------------------------------
 SRID=4326;LINESTRING(0 0,10 0,10 10,5 5,0 5)
```

# ST\$1LineInterpolatePoint
<a name="ST_LineInterpolatePoint-function"></a>

ST\$1LineInterpolatePoint 返回一条直线上距离该线起点一小段距离的一个点。

要确定点相等性，ST\$1LineInterpolatePoint 对输入几何体的 2D 投影进行操作。如果输入几何体为空，则返回该几何体的维度与输入相同的副本。对于 3DZ、3DM 和 4D 几何体，`z` 或 `m` 坐标点所在线段的 `z` 或 `m` 坐标的平均值。

## 语法
<a name="ST_LineInterpolatePoint-function-syntax"></a>

```
ST_LineInterpolatePoint(geom, fraction)
```

## 参数
<a name="ST_LineInterpolatePoint-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型为 `LINESTRING`。

 *fraction*   
数据类型 `DOUBLE PRECISION` 的一个值，表示点沿着线的线串的位置。该值是介于 0—1 范围内的一个分数，包含首尾。

## 返回类型
<a name="ST_LineInterpolatePoint-function-return"></a>

`GEOMETRY`子类型 的 `POINT`。

如果 *geom* 或 *fraction* 为 null，则返回 null。

如果 *geom* 为空，则返回一个空点。

返回的几何体的空间参考系统标识符 (SRID) 值是输入几何体的 SRID 值。

如果 *fraction* 超出范围，则返回一个错误。

如果 *geom* 不是线串，则返回一个错误。

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

以下 SQL 返回沿线串中途的点。

```
SELECT ST_AsEWKT(ST_LineInterpolatePoint(ST_GeomFromText('LINESTRING(0 0, 5 5, 7 7, 10 10)'), 0.50));
```

```
st_asewkt
-----------
 POINT(5 5)
```

以下 SQL 返回沿线串行程 90% 的点。

```
SELECT ST_AsEWKT(ST_LineInterpolatePoint(ST_GeomFromText('LINESTRING(0 0, 5 5, 7 7, 10 10)'), 0.90));
```

```
st_asewkt
-----------
 POINT(9 9)
```

# ST\$1M
<a name="ST_M-function"></a>

ST\$1M 返回输入点的 `m` 坐标。

## 语法
<a name="ST_M-function-syntax"></a>

```
ST_M(point)
```

## 参数
<a name="ST_M-function-arguments"></a>

 *point*   
一个 `POINT` 数据类型的 `GEOMETRY` 值。

## 返回类型
<a name="ST_M-function-return"></a>

`m` 坐标的 `DOUBLE PRECISION` 值。

如果 *point* 为 null，则返回 null。

如果 *point* 是 2D 或 3DZ 点，则返回 null。

如果 *point* 是空点，则返回 null。

如果 *point* 不是 `POINT`，则返回一个错误。

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

以下 SQL 返回 3DM 几何体中一个点的 `m` 坐标。

```
SELECT ST_M(ST_GeomFromEWKT('POINT M (1 2 3)'));
```

```
st_m
-----------
 3
```

以下 SQL 返回 4D 几何体中一个点的 `m` 坐标。

```
SELECT ST_M(ST_GeomFromEWKT('POINT ZM (1 2 3 4)'));
```

```
st_m
-----------
 4
```

# ST\$1MakeEnvelope
<a name="ST_MakeEnvelope-function"></a>

ST\$1MakeEnvelope 返回一个几何体，如下所示：
+ 如果输入坐标指定一个点，则返回的几何体是一个点。
+ 如果输入坐标指定一条线，则返回的几何为线串。
+ 否则，返回的几何体位面，其中输入坐标指定框的左下角和右上角。

返回的几何体的空间参考系统标识符 (SRID) 值（如有提供）将设置为输入 SRID 值。

## 语法
<a name="ST_MakeEnvelope-function-syntax"></a>

```
ST_MakeEnvelope(xmin, ymin, xmax, ymax)
```

```
ST_MakeEnvelope(xmin, ymin, xmax, ymax, srid)
```

## 参数
<a name="ST_MakeEnvelope-function-arguments"></a>

 *xmin*   
一个 数据类型的 值`DOUBLE PRECISION` 此值是框左下角的第一个坐标。

 *ymin*   
一个 数据类型的 值`DOUBLE PRECISION` 此值是框左下角的第二个坐标。

 *xmax*   
一个 数据类型的 值`DOUBLE PRECISION` 此值是框右上角的第一个坐标。

 *ymax*   
一个 数据类型的 值`DOUBLE PRECISION` 此值是框右上角的第二个坐标。

 *srid*   
数据类型 `INTEGER` 的一个值，它表示空间参考系统标识符 (SRID)。如果未提供 SRID 值，则它会设置为零。

## 返回类型
<a name="ST_MakeEnvelope-function-return"></a>

子类型 `POINT`、`LINESTRING` 或 `POLYGON` 的 `GEOMETRY`。

返回的几何体的 SRID 将设置为 `srid`，如果未设置 `srid`，则设置为零。

如果 *xmin*、*ymin*、*xmax*、*ymax* 或 *srid* 为 null，则返回 null。

如果 *srid* 为负，则返回一个错误。

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

以下 SQL 会返回一个面，表示由四个输入坐标值定义的信封。

```
SELECT ST_AsEWKT(ST_MakeEnvelope(2,4,5,7));
```

```
 st_astext
---------------
 POLYGON((2 4,2 7,5 7,5 4,2 4))
```

以下 SQL 会返回一个面，表示由四个输入坐标值和一个 SRID 值定义的信封。

```
SELECT ST_AsEWKT(ST_MakeEnvelope(2,4,5,7,4326));
```

```
 st_astext
----------------------------------
 SRID=4326;POLYGON((2 4,2 7,5 7,5 4,2 4))
```

# ST\$1MakeLine
<a name="ST_MakeLine-function"></a>

ST\$1MakeLine 从输入几何体创建线串。

返回的几何体的维度与输入几何体的维度相同。两个输入几何体必须具有相同的维度。

## 语法
<a name="ST_MakeLine-function-syntax"></a>

```
ST_MakeLine(geom1, geom2)
```

## 参数
<a name="ST_MakeLine-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `POINT`、`LINESTRING` 或 `MULTIPOINT`。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `POINT`、`LINESTRING` 或 `MULTIPOINT`。

## 返回类型
<a name="ST_MakeLine-function-return"></a>

`GEOMETRY`子类型 的 `LINESTRING`。

如果 *geom1* 或 *geom2* 为 null，则返回 null。

如果 *geom1* 和 *geom2* 为空点或包含空点，则忽略这些空点。

如果 *geom1* 和 *geom2* 为空，则返回空 `LINESTRING`。

返回的几何体的空间参考系统标识符 (SRID) 值是输入几何体的 SRID 值。

如果 *geom1* 和 *geom2* 具有不同的 SRID 值，则返回一个错误。

如果 *geom1* 或 *geom2* 不为 `POINT`、`LINESTRING` 或 `MULTIPOINT`，则返回一个错误。

如果 *geom1* 和 *geom2* 具有不同的维度，则返回一个错误。

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

以下 SQL 从两个输入线串构造一个线串。

```
SELECT ST_MakeLine(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'), ST_GeomFromText('LINESTRING(88.29 39.07,88.42 39.26,88.27 39.31,88.29 39.07)'));
```

```
st_makeline
-----------
 010200000008000000C3F5285C8F52534052B81E85EB113D407B14AE47E15A5340C3F5285C8F423D40E17A14AE475153408FC2F5285C4F3D40C3F5285C8F52534052B81E85EB113D40C3F5285C8F125640295C8FC2F58843407B14AE47E11A5640E17A14AE47A14340E17A14AE4711564048E17A14AEA74340C3F5285C8F125640295C8FC2F5884340
```

# ST\$1MakePoint
<a name="ST_MakePoint-function"></a>

ST\$1MakePoint 返回其坐标值为输入值的点几何体。

## 语法
<a name="ST_MakePoint-function-syntax"></a>

```
ST_MakePoint(x, y)
```

```
ST_MakePoint(x, y, z)
```

```
ST_MakePoint(x, y, z, m)
```

## 参数
<a name="ST_MakePoint-function-arguments"></a>

 *x*   
一个 `DOUBLE PRECISION` 数据类型的值，该值表示第一个坐标。

 *y*   
一个 `DOUBLE PRECISION` 数据类型的值，该值表示第二个坐标。

 *z*   
数据类型 `DOUBLE PRECISION` 的一个值，该值表示第三个坐标。

 *m*   
数据类型 `DOUBLE PRECISION` 的一个值，该值表示第四个坐标。

## 返回类型
<a name="ST_MakePoint-function-return"></a>

`GEOMETRY`子类型 的 `POINT`。

返回的几何体的空间参考系统标识符 (SRID) 值将设置为 0。

如果 *x*、*y*、*z* 或 *m* 为 null，则返回 null。

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

以下 SQL 返回子类型 `GEOMETRY` 的 `POINT` 类型以及提供的坐标。

```
SELECT ST_AsText(ST_MakePoint(1,3));
```

```
st_astext
-----------
 POINT(1 3)
```

以下 SQL 返回子类型 `GEOMETRY` 的 `POINT` 类型以及提供的坐标。

```
SELECT ST_AsEWKT(ST_MakePoint(1, 2, 3));
```

```
st_asewkt
----------------
 POINT Z (1 2 3)
```

以下 SQL 返回子类型 `GEOMETRY` 的 `POINT` 类型以及提供的坐标。

```
SELECT ST_AsEWKT(ST_MakePoint(1, 2, 3, 4));
```

```
st_asewkt
-------------------
 POINT ZM (1 2 3 4)
```

# ST\$1MakePolygon
<a name="ST_MakePolygon-function"></a>

ST\$1MakePolygon 具有两个可返回面的变体。一个采用单个几何体，另一个采用两个几何体。
+ 第一个变体的输入是定义输出面的外环的线串。
+ 第二个变体的输入是一个线串和一个多线串。两个都是空的或闭合的。

  输出面外环的边界是输入线串，而面内环的边界是输入多线串中的线串。如果输入线串为空，则返回空面。多线串中的空线串将被忽略。生成的几何体的空间参考系统标识符 (SRID) 是两个输入几何体的共同 SRID。

返回的几何体的维度与输入几何体的维度相同。外环和内环必须具有相同维度。

## 语法
<a name="ST_MakePolygon-function-syntax"></a>

```
ST_MakePolygon(geom1)
```

```
ST_MakePolygon(geom1, geom2)
```

## 参数
<a name="ST_MakePolygon-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `LINESTRING`。*linestring* 值必须是闭合的或为空。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `MULTILINESTRING`。

## 返回类型
<a name="ST_MakePolygon-function-return"></a>

`GEOMETRY`子类型 的 `POLYGON`。

返回的几何体的空间参考系统标识符 (SRID) 等于输入的 SRID。

如果 *geom1* 或 *geom2* 为 null，则返回 null。

如果 *geom1* 不是线串，则返回一个错误。

如果 *geom2* 不是多线串，则返回一个错误。

如果 *geom1* 不是闭合的，则返回一个错误。

如果 *geom1* 是单个点或者不是闭合的，则返回一个错误。

如果 *geom2* 至少包含一个具有单个点或未闭合的线串，则返回一个错误。

如果 *geom1* 和 *geom2* 具有不同的 SRID 值，则返回一个错误。

如果 *geom1* 和 *geom2* 具有不同的维度，则返回一个错误。

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

以下 SQL 从输入线串返回多边形。

```
SELECT ST_AsText(ST_MakePolygon(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)')));
```

```
 st_astext
---------------
POLYGON((77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07))
```

以下 SQL 根据闭合线串和闭合多线串创建面。线串用于面的外环。多线串中的线串用于面的内环。

```
SELECT ST_AsEWKT(ST_MakePolygon(ST_GeomFromText('LINESTRING(0 0,10 0,10 10,0 10,0 0)'), ST_GeomFromText('MULTILINESTRING((1 1,1 2,2 1,1 1),(3 3,3 4,4 3,3 3))')));
```

```
 st_astext
----------------------------------
POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,1 2,2 1,1 1),(3 3,3 4,4 3,3 3))
```

# ST\$1MemSize
<a name="ST_MemSize-function"></a>

ST\$1MemSize 返回输入几何体所使用的内存空间量（以字节为单位）。此大小取决于几何体的 Amazon Redshift 内部表示形式，因此，如果内部表示形式发生变化，则大小会发生变化。可以将此大小用作 Amazon Redshift 中几何体对象的相对大小的指示。

## 语法
<a name="ST_MemSize-function-syntax"></a>

```
ST_MemSize(geom)
```

## 参数
<a name="ST_MemSize-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_MemSize-function-return"></a>

`INTEGER`，表示 *geom* 的固有维度。

如果 *geom* 为 null，则返回 null。

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

以下 SQL 返回几何体集合的内存大小。

```
SELECT ST_MemSize(ST_GeomFromText('GEOMETRYCOLLECTION(POLYGON((0 0,10 0,0 10,0 0)),LINESTRING(20 10,20 0,10 0))'))::varchar + ' bytes';
```

```
 ?column?  
-----------
 172 bytes
```

# ST\$1MMax
<a name="ST_MMax-function"></a>

ST\$1MMax 返回输入几何体的最大的 `m` 坐标。

## 语法
<a name="ST_MMax-function-syntax"></a>

```
ST_MMax(geom)
```

## 参数
<a name="ST_MMax-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_MMax-function-return"></a>

最大的 `m` 坐标的 `DOUBLE PRECISION` 值。

如果 *geom* 为空，则返回 null。

如果 *geom* 为 null，则返回 null。

如果 *geom* 是 2D 或 3DZ 几何体，则返回 null。

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

以下 SQL 返回 3DM 几何体中一个线串的最大 `m` 坐标。

```
SELECT ST_MMax(ST_GeomFromEWKT('LINESTRING M (0 1 2, 3 4 5, 6 7 8)'));
```

```
st_mmax
-----------
  8
```

以下 SQL 返回 4D 几何体中一个线串的最大 `m` 坐标。

```
SELECT ST_MMax(ST_GeomFromEWKT('LINESTRING ZM (0 1 2 3, 4 5 6 7, 8 9 10 11)'));
```

```
st_mmax
-----------
  11
```

# ST\$1MMin
<a name="ST_MMin-function"></a>

ST\$1MMin 返回输入几何体的最小 `m` 坐标。

## 语法
<a name="ST_MMin-function-syntax"></a>

```
ST_MMin(geom)
```

## 参数
<a name="ST_MMin-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_MMin-function-return"></a>

最小 `m` 坐标的 `DOUBLE PRECISION` 值。

如果 *geom* 为空，则返回 null。

如果 *geom* 为 null，则返回 null。

如果 *geom* 是 2D 或 3DZ 几何体，则返回 null。

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

以下 SQL 返回 3DM 几何体中一个线串的最小 `m` 坐标。

```
SELECT ST_MMin(ST_GeomFromEWKT('LINESTRING M (0 1 2, 3 4 5, 6 7 8)'));
```

```
st_mmin
-----------
  2
```

以下 SQL 返回 4D 几何体中一个线串的最小 `m` 坐标。

```
SELECT ST_MMin(ST_GeomFromEWKT('LINESTRING ZM (0 1 2 3, 4 5 6 7, 8 9 10 11)'));
```

```
st_mmin
-----------
  3
```

# ST\$1Multi
<a name="ST_Multi-function"></a>

ST\$1Multi 将几何体转换为相应的多类型。如果输入几何体已经是多类型或几何体集合，则返回其副本。如果输入几何体是点、线串或面，则返回包含输入几何体的多点、多线串或多面。

## 语法
<a name="ST_Multi-function-syntax"></a>

```
ST_Multi(geom)
```

## 参数
<a name="ST_Multi-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Multi-function-return"></a>

带子类型 `MULTIPOINT`、`MULTILINESTRING`、`MULTIPOLYGON` 或 `GEOMETRYCOLLECTION` 的 `GEOMETRY`。

返回的几何体的空间参考系统标识符 (SRID) 与输入几何体的相同。

如果 *geom* 为 null，则返回 null。

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

以下 SQL 从输入多点返回多点。

```
SELECT ST_AsEWKT(ST_Multi(ST_GeomFromText('MULTIPOINT((1 2),(3 4))', 4326)));
```

```
    st_asewkt
------------------------------------
  SRID=4326;MULTIPOINT((1 2),(3 4))
```

以下 SQL 从输入点返回多点。

```
SELECT ST_AsEWKT(ST_Multi(ST_GeomFromText('POINT(1 2)', 4326)));
```

```
    st_asewkt
------------------------------------
  SRID=4326;MULTIPOINT((1 2))
```

以下 SQL 返回输入几何体集合中返回几何体集合。

```
SELECT ST_AsEWKT(ST_Multi(ST_GeomFromText('GEOMETRYCOLLECTION(POINT(1 2),MULTIPOINT((1 2),(3 4)))', 4326)));
```

```
    st_asewkt
------------------------------------
  SRID=4326;GEOMETRYCOLLECTION(POINT(1 2),MULTIPOINT((1 2),(3 4)))
```

# ST\$1NDims
<a name="ST_NDims-function"></a>

ST\$1NDims 返回几何体的坐标维度。ST\$1NDims 不考虑几何体的拓扑维度。相反，它会根据几何体的维度返回一个常量值。

## 语法
<a name="ST_NDims-function-syntax"></a>

```
ST_NDims(geom)
```

## 参数
<a name="ST_NDims-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_NDims-function-return"></a>

`INTEGER`，表示 *geom* 的固有维度。

如果 *geom* 为 null，则返回 null。

返回的值如下所示。


| 返回的值 | 输入几何体的维度 | 
| --- | --- | 
| 2 | 2D | 
| 3 | 3DZ 或 3DM | 
| 4 | 4D | 

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

以下 SQL 返回 2D 线串的维数。

```
SELECT ST_NDims(ST_GeomFromText('LINESTRING(0 0,1 1,2 2,0 0)'));
```

```
st_ndims
-------------
 2
```

以下 SQL 返回 3DZ 线串的维数。

```
SELECT ST_NDims(ST_GeomFromText('LINESTRING Z(0 0 3,1 1 3,2 2 3,0 0 3)'));
```

```
st_ndims
-------------
 3
```

以下 SQL 返回 3DM 线串的维数。

```
SELECT ST_NDims(ST_GeomFromText('LINESTRING M(0 0 4,1 1 4,2 2 4,0 0 4)'));
```

```
st_ndims
-------------
 3
```

以下 SQL 返回 4D 线串的维数。

```
SELECT ST_NDims(ST_GeomFromText('LINESTRING ZM(0 0 3 4,1 1 3 4,2 2 3 4,0 0 3 4)'));
```

```
st_ndims
-------------
 4
```

# ST\$1NPoints
<a name="ST_NPoints-function"></a>

ST\$1NPoints 返回输入几何体或地理中的非空点数量。

## 语法
<a name="ST_NPoints-function-syntax"></a>

```
ST_NPoints(geo)
```

## 参数
<a name="ST_NPoints-function-arguments"></a>

 *geo*   
一个 `GEOMETRY` 或 `GEOGRAPHY` 数据类型的值，或一个计算结果为 `GEOMETRY` 或 `GEOGRAPHY` 类型的表达式。

## 返回类型
<a name="ST_NPoints-function-return"></a>

`INTEGER`

如果 *geo* 为空点，则返回 `0`。

如果 *geo* 为 null，则返回 null。

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

以下 SQL 返回线串中的点数。

```
SELECT ST_NPoints(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'));
```

```
st_npoints
-------------
 4
```

以下 SQL 返回几何体中线串中的点数。

```
SELECT ST_NPoints(ST_GeogFromText('LINESTRING(110 40, 2 3, -10 80, -7 9)'));
```

```
st_npoints
-------------
 4
```

# ST\$1NRings
<a name="ST_NRings-function"></a>

ST\$1NRings 返回输入几何体中的环形数。

## 语法
<a name="ST_NRings-function-syntax"></a>

```
ST_NRings(geom)
```

## 参数
<a name="ST_NRings-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_NRings-function-return"></a>

`INTEGER`

如果 *geom* 为 null，则返回 null。

返回的值如下所示。


| 返回的值 | 几何体子类型 | 
| --- | --- | 
| 0 | 在 *geom* 为 `POINT`、`LINESTRING`、`MULTIPOINT` 或 `MULTILINESTRING` 子类型时返回  | 
| 环形的数量。 | 在 *geom* 为 `POLYGON` 或 `MULTIPOLYGON` 子类型时返回 | 
| 所有组件中的环形数 | 在 *geom* 为 `GEOMETRYCOLLECTION` 子类型时返回 | 

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

以下 SQL 返回多边形集合中的环形数。

```
SELECT ST_NRings(ST_GeomFromText('MULTIPOLYGON(((0 0,10 0,0 10,0 0)),((0 0,-10 0,0 -10,0 0)))'));
```

```
 st_nrings
-------------
 2
```

# ST\$1NumGeometries
<a name="ST_NumGeometries-function"></a>

ST\$1NumGeometries 返回输入几何体中的几何体数。

## 语法
<a name="ST_NumGeometries-function-syntax"></a>

```
ST_NumGeometries(geom)
```

## 参数
<a name="ST_NumGeometries-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_NumGeometries-function-return"></a>

`INTEGER`，表示 *geom* 中的几何体数。

如果 *geom* 为 null，则返回 null。

如果 *geom* 是单个空几何体，则返回 `0`。

如果 *geom* 是单个非空几何体，则返回 `1`。

如果 *geom* 为 `GEOMETRYCOLLECTION` 或 `MULTI` 子类型，则返回几何体数。

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

以下 SQL 返回输入线串集合中的几何体数量。

```
SELECT ST_NumGeometries(ST_GeomFromText('MULTILINESTRING((0 0,1 0,0 5),(3 4,13 26))'));
```

```
st_numgeometries
-------------
 2
```

# ST\$1NumInteriorRings
<a name="ST_NumInteriorRings-function"></a>

ST\$1NumInteriorRings 返回输入多边形几何体中的环形数。

## 语法
<a name="ST_NumInteriorRings-function-syntax"></a>

```
ST_NumInteriorRings(geom)
```

## 参数
<a name="ST_NumInteriorRings-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_NumInteriorRings-function-return"></a>

`INTEGER`

如果 *geom* 为 null，则返回 null。

如果 *geom* 不是多边形，则返回 null。

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

以下 SQL 返回输入多边形中的内环数。

```
SELECT ST_NumInteriorRings(ST_GeomFromText('POLYGON((0 0,100 0,100 100,0 100,0 0),(1 1,1 5,5 1,1 1),(7 7,7 8,8 7,7 7))'));
```

```
 st_numinteriorrings
-------------
 2
```

# ST\$1NumPoints
<a name="ST_NumPoints-function"></a>

ST\$1NumPoints 返回输入几何体中的点数。

## 语法
<a name="ST_NumPoints-function-syntax"></a>

```
ST_NumPoints(geom)
```

## 参数
<a name="ST_NumPoints-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_NumPoints-function-return"></a>

`INTEGER`

如果 *geom* 为 null，则返回 null。

如果 *geom* 不属于子类型 `LINESTRING`，则返回 null。

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

以下 SQL 返回输入线串中的点数。

```
SELECT ST_NumPoints(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'));
```

```
st_numpoints
-------------
4
```

以下 SQL 返回 null，因为输入 *geom* 不属于子类型 `LINESTRING`。

```
SELECT ST_NumPoints(ST_GeomFromText('MULTIPOINT(1 2,3 4)'));
```

```
st_numpoints
-------------
```

# ST\$1Perimeter
<a name="ST_Perimeter-function"></a>

对于输入平面几何体，ST\$1Perimeter 返回 2D 投影的笛卡尔周长（边界长度）。周长单位与用于表示输入几何体坐标的单位相同。对于点、多点和线性几何体，此函数返回零 (0)。当输入为几何体集合时，此函数返回集合中的几何体周长之和。

对于输入平面地理，ST\$1Piameter 返回由 SRID 确定的在椭球体上计算的输入平面地理的 2D 投影的测地线周长（边界长度）。周长以米为单位。对于点、多点和线性地理，此函数返回零 (0)。当输入为几何体集合时，此函数返回集合中的地理周长之和。

## 语法
<a name="ST_Perimeter-function-syntax"></a>

```
ST_Perimeter(geo)
```

## 参数
<a name="ST_Perimeter-function-arguments"></a>

 *geo*   
一个 `GEOMETRY` 或 `GEOGRAPHY` 数据类型的值，或一个计算结果为 `GEOMETRY` 或 `GEOGRAPHY` 类型的表达式。

## 返回类型
<a name="ST_Perimeter-function-return"></a>

`DOUBLE PRECISION`

如果 *geo* 为 null，则返回 null。

如果找不到 SRID 值，则返回一个错误。

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

以下 SQL 返回多边形的笛卡尔周长。

```
SELECT ST_Perimeter(ST_GeomFromText('MULTIPOLYGON(((0 0,10 0,0 10,0 0)),((10 0,20 0,20 10,10 0)))'));
```

```
 st_perimeter
--------------------------------
    68.2842712474619
```

以下 SQL 返回多边形的笛卡尔周长。

```
SELECT ST_Perimeter(ST_GeomFromText('MULTIPOLYGON(((0 0,10 0,0 10,0 0)),((10 0,20 0,20 10,10 0)))'));
```

```
 st_perimeter
--------------------------------
    68.2842712474619
```

以下 SQL 返回地理中的多边形周长。

```
SELECT ST_Perimeter(ST_GeogFromText('SRID=4326;POLYGON((0 0,1 0,0 1,0 0))'));
```

```
 st_perimeter 
------------------
 378790.428393693
```

以下 SQL 返回地理中线串的周长。

```
SELECT ST_Perimeter(ST_GeogFromText('SRID=4326;LINESTRING(5 0,10 0)'));
```

```
 st_perimeter 
--------------
 0
```

# ST\$1Perimeter2D
<a name="ST_Perimeter2D-function"></a>

ST\$1Perimeter2D 是 ST\$1Perimeter 的别名。有关更多信息，请参阅 [ST\$1Perimeter](ST_Perimeter-function.md)。

# ST\$1Point
<a name="ST_Point-function"></a>

ST\$1Point 从输入坐标值返回点几何体。

## 语法
<a name="ST_Point-function-syntax"></a>

```
ST_Point(x, y)
```

## 参数
<a name="ST_Point-function-arguments"></a>

 *x*   
一个 `DOUBLE PRECISION` 数据类型的值，该值表示第一个坐标。

 *y*   
一个 `DOUBLE PRECISION` 数据类型的值，该值表示第二个坐标。

## 返回类型
<a name="ST_Point-function-return"></a>

`GEOMETRY`子类型 的 `POINT`。

返回的几何体的空间参考系统标识符 (SRID) 值将设置为 0。

如果 *x* 或 *y* 为 null，则返回 null。

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

以下 SQL 从输入坐标构造点几何体。

```
SELECT ST_AsText(ST_Point(5.0, 7.0));
```

```
st_astext
-------------
POINT(5 7)
```

# ST\$1PointN
<a name="ST_PointN-function"></a>

ST\$1PointN 返回由索引值指定的线串中的点。负索引值从线串的末尾开始倒计数，因此 -1 是最后一个点。

返回的几何体的维度与输入几何体的维度相同。

## 语法
<a name="ST_PointN-function-syntax"></a>

```
ST_PointN(geom, index)
```

## 参数
<a name="ST_PointN-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `LINESTRING`。

 *index*   
一个 `INTEGER` 数据类型的值，表示线串中的点的索引。

## 返回类型
<a name="ST_PointN-function-return"></a>

`GEOMETRY`子类型 的 `POINT`。

返回的几何体的空间参考系统标识符 (SRID) 值将设置为 0。

如果 *geom* 或 *index* 为 null，则返回 null。

如果 *index* 超出范围，则返回 null。

如果 *geom* 为空，则返回 null。

如果 *geom* 不为 `LINESTRING`，则返回 null。

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

以下 SQL 将六点 `LINESTRING` 的扩展的已知文本 (EWKT) 表示形式返回到 `GEOMETRY` 对象，并返回线串的索引 5 的点。

```
SELECT ST_AsEWKT(ST_PointN(ST_GeomFromText('LINESTRING(0 0,10 0,10 10,5 5,0 5,0 0)',4326), 5));
```

```
st_asewkt
-------------
 SRID=4326;POINT(0 5)
```

# ST\$1Points
<a name="ST_Points-function"></a>

ST\$1Points 返回包含输入几何体中所有非空点的多点几何体。ST\$1Points 不会移除输入中重复的点，包括环形几何体的起点和终点。

## 语法
<a name="ST_Points-function-syntax"></a>

```
ST_Points(geom)
```

## 参数
<a name="ST_Points-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Points-function-return"></a>

`GEOMETRY`子类型 的 `MULTIPOINT`。

返回的几何体的空间参考系统标识符 (SRID) 值与 *geom* 相同。

如果 *geom* 为 null，则返回 null。

如果 *geom* 为空，则返回一个空的多点。

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

以下 SQL 示例根据输入几何体构建多点几何体。结果产生包含输入几何体中的非空点的多点几何体。

```
SELECT ST_AsEWKT(ST_Points(ST_SetSRID(ST_GeomFromText('LINESTRING(1 0,2 0,3 0)'), 4326)));
```

```
st_asewkt
-------------
SRID=4326;MULTIPOINT((1 0),(2 0),(3 0))
```

```
SELECT ST_AsEWKT(ST_Points(ST_SetSRID(ST_GeomFromText('MULTIPOLYGON(((0 0,1 0,0 1,0 0)))'), 4326)));
```

```
st_asewkt
-------------
SRID=4326;MULTIPOINT((0 0),(1 0),(0 1),(0 0))
```

# ST\$1Polygon
<a name="ST_Polygon-function"></a>

ST\$1Polygon 返回一个多边形几何体，其外部环形是输入线串，其值是空间参考系统标识符 (SRID) 的输入值。

返回的几何体的维度与输入几何体的维度相同。

## 语法
<a name="ST_Polygon-function-syntax"></a>

```
ST_Polygon(linestring, srid)
```

## 参数
<a name="ST_Polygon-function-arguments"></a>

 *linestring*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是表示线串的 `LINESTRING`。*linestring* 值必须是闭合的。

 *srid*   
一个 `INTEGER` 数据类型的值，该值表示一个 SRID。

## 返回类型
<a name="ST_Polygon-function-return"></a>

`GEOMETRY`子类型 的 `POLYGON`。

返回的几何体的 SRID 值将设置为 *srid*。

如果 *linestring* 或 *srid* 为 null，则返回 null。

如果 *linestring* 不是线串，则返回一个错误。

如果 *linestring* 未闭合，则返回一个错误。

如果 *srid* 为负，则返回一个错误。

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

以下 SQL 构造一个具有 SRID 值的多边形。

```
SELECT ST_AsEWKT(ST_Polygon(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'),4356));
```

```
st_asewkt
-------------
 SRID=4356;POLYGON((77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07))
```

# ST\$1RemovePoint
<a name="ST_RemovePoint-function"></a>

ST\$1RemovePoint 返回一个线串几何体，该几何体已删除输入几何体在索引位置的点。

索引是从零开始的。结果的空间参考系统标识符 (SRID) 与输入几何体的相同。返回的几何体的维度与输入几何体的维度相同。

## 语法
<a name="ST_RemovePoint-function-syntax"></a>

```
ST_RemovePoint(geom, index)
```

## 参数
<a name="ST_RemovePoint-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `LINESTRING`。

 *index*   
一个 `INTEGER` 数据类型的值，表示从零开始的索引的位置。

## 返回类型
<a name="ST_RemovePoint-function-return"></a>

`GEOMETRY` 

如果 *geom* 或 *index* 为 null，则返回 null。

如果 *geom* 不是子类型 `LINESTRING`，则返回错误。

如果 *index* 超出范围，则返回一个错误。索引位置的有效值为 0 到 `ST_NumPoints(geom)` 减 1。

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

以下 SQL 删除线串中的最后一个点。

```
WITH tmp(g) AS (SELECT ST_GeomFromText('LINESTRING(0 0,10 0,10 10,5 5,0 5)',4326))
SELECT ST_AsEWKT(ST_RemovePoint(g, ST_NumPoints(g) - 1)) FROM tmp;
```

```
   st_asewkt
-----------------------------------------
 SRID=4326;LINESTRING(0 0,10 0,10 10,5 5)
```

# ST\$1Reverse
<a name="ST_Reverse-function"></a>

ST\$1Reverse 可反转线性几何体和平面几何体的顶点顺序。对于点或多点几何体，将返回原始几何体的副本。对于几何体集合，ST\$1Reverse 将反转集合中每个几何体的顶点顺序。

返回的几何体的维度与输入几何体的维度相同。

## 语法
<a name="ST_Reverse-function-syntax"></a>

```
ST_Reverse(geom)
```

## 参数
<a name="ST_Reverse-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Reverse-function-return"></a>

`GEOMETRY` 

返回的几何体的空间参考系统标识符 (SRID) 与输入几何体的相同。

如果 *geom* 为 null，则返回 null。

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

以下 SQL 反转线串中点的顺序。

```
SELECT ST_AsEWKT(ST_Reverse(ST_GeomFromText('LINESTRING(1 0,2 0,3 0,4 0)', 4326)));
```

```
    st_asewkt
------------------------------------
  SRID=4326;LINESTRING(4 0,3 0,2 0,1 0)
```

# ST\$1SetPoint
<a name="ST_SetPoint-function"></a>

ST\$1SetPoint 返回一个线串，该线串具有相对于索引指定的输入线串位置的更新坐标。新坐标是输入点的坐标。

返回的几何体的维度与 *geom1* 值的相同。如果 *geom1* 和 *geom2* 具有不同的维度，则 *geom2* 会投影到 *geom1* 的维度。

## 语法
<a name="ST_SetPoint-function-syntax"></a>

```
ST_SetPoint(geom1, index, geom2)
```

## 参数
<a name="ST_SetPoint-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `LINESTRING`。

 *index*   
数据类型 `INTEGER` 的一个值，表示索引的位置。`0` 是指从左边开始的线串的第一个点，`1` 指的是第二点，依此类推。索引可以是负值。`-1` 是指从右边开始的线串的第一个点，`-2` 指的是从右边开始的线串的第二点，依此类推。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `POINT`。

## 返回类型
<a name="ST_SetPoint-function-return"></a>

`GEOMETRY`

如果 *geom2* 是空点，则会返回 *geom1*。

如果 *geom1*、*geom2* 或 *index* 为 null，则返回 null。

如果 *geom1* 不是线串，则返回一个错误。

如果 *index* 不在有效的索引范围内，则返回一个错误。

如果 *geom2* 不是点，则返回一个错误。

如果 *geom1* 和 *geom2* 不具有相同的空间参考系统标识符 (SRID) 值，则返回一个错误。

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

以下 SQL 返回一个新的线串，其中我们用指定的点设置了输入线串的第二个点。

```
SELECT ST_AsText(ST_SetPoint(ST_GeomFromText('LINESTRING(1 2, 3 2, 5 2, 1 2)'), 2, ST_GeomFromText('POINT(7 9)')));
```

```
st_astext              
-------------
 LINESTRING(1 2,3 2,7 9,1 2)
```

以下 SQL 示例返回一个新的线串，其中我们用指定的点设置了线串右起第三个点（索引为负数）。

```
SELECT ST_AsText(ST_SetPoint(ST_GeomFromText('LINESTRING(1 2, 3 2, 5 2, 1 2)'), -3, ST_GeomFromText('POINT(7 9)')));
```

```
st_astext              
-------------
 LINESTRING(1 2,7 9,5 2,1 2)
```

# ST\$1SetSRID
<a name="ST_SetSRID-function"></a>

ST\$1SetSRID 返回一个与输入几何体相同的几何体，只不过使用空间参考系统标识符 (SRID) 的输入值进行了更新。

## 语法
<a name="ST_SetSRID-function-syntax"></a>

```
ST_SetSRID(geom, srid)
```

## 参数
<a name="ST_SetSRID-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *srid*   
一个 `INTEGER` 数据类型的值，该值表示一个 SRID。

## 返回类型
<a name="ST_SetSRID-function-return"></a>

`GEOMETRY`

返回的几何体的 SRID 值将设置为 *srid*。

如果 *geom* 或 *srid* 为 null，则返回 null。

如果 *srid* 为负，则返回一个错误。

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

以下 SQL 设置线串的 SRID 值。

```
SELECT ST_AsEWKT(ST_SetSRID(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'),50));
```

```
st_asewkt
-------------
 SRID=50;LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)
```

# ST\$1Simplify
<a name="ST_Simplify-function"></a>

ST\$1Simplify 使用带有给定容差的 Ramer-Douglas-Peucker 算法返回输入几何体的简化副本。输入几何体的拓扑结构可能不会保留。有关该算法的更多信息，请参阅 Wikipedia 中的 [Ramer–Douglas–Peucker 算法](https://en.wikipedia.org/wiki/Ramer–Douglas–Peucker_algorithm)。

当 ST\$1Simplify 计算距离以简化几何体时，ST\$1Simplify 会对输入几何体的 2D 投影进行操作。

## 语法
<a name="ST_Simplify-function-syntax"></a>

```
ST_Simplify(geom, tolerance)
```

## 参数
<a name="ST_Simplify-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *tolerance*   
数据类型 `DOUBLE PRECISION` 的一个值，表示 Ramer-Douglas-Peucker 算法的容差水平。如果 *tolerance* 是负数，则使用零。

## 返回类型
<a name="ST_Simplify-function-return"></a>

`GEOMETRY`. 

返回的几何体的空间参考系统标识符 (SRID) 值是输入几何体的 SRID 值。

返回的几何体的维度与输入几何体的维度相同。

如果 *geom* 为 null，则返回 null。

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

以下 SQL 通过 Ramer-Douglas-Peucker 算法，使用欧几里得距离容差 1 简化了输入线串。距离的单位与几何体坐标的单位相同。

```
SELECT ST_AsEWKT(ST_Simplify(ST_GeomFromText('LINESTRING(0 0,1 2,1 1,2 2,2 1)'), 1));
```

```
 st_asewkt
-----------
LINESTRING(0 0,1 2,2 1)
```

# ST\$1SRID
<a name="ST_SRID-function"></a>

ST\$1SRID 返回输入几何体的空间参考系统标识符 (SRID)。有关 SRID 的更多信息，请参阅[在 Amazon Redshift 中查询空间数据](geospatial-overview.md)。

## 语法
<a name="ST_SRID-function-syntax"></a>

```
ST_SRID(geom)
```

## 参数
<a name="ST_SRID-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_SRID-function-return"></a>

`INTEGER`，表示 *geom* 的 SRID 值。

如果 *geom* 为 null，则返回 null。

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

以下 SQL 返回线串的 SRID 值，该线串设置为 SRID `4326`。

```
SELECT ST_SRID(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)',4326));
```

```
st_srid
-------------
 4326
```

以下 SQL 返回线串的 SRID 值，该线串在构造时未设置。这导致 SRID 值为 `0`。

```
SELECT ST_SRID(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'));
```

```
st_srid
-------------
 0
```

# ST\$1StartPoint
<a name="ST_StartPoint-function"></a>

ST\$1StartPoint 返回输入线串的第一个点。结果的空间参考系统标识符 (SRID) 值与输入几何体的相同。返回的几何体的维度与输入几何体的维度相同。

## 语法
<a name="ST_StartPoint-function-syntax"></a>

```
ST_StartPoint(geom)
```

## 参数
<a name="ST_StartPoint-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。子类型必须是 `LINESTRING`。

## 返回类型
<a name="ST_StartPoint-function-return"></a>

`GEOMETRY` 

如果 *geom* 为 null，则返回 null。

如果 *geom* 为空，则返回 null。

如果 *geom* 不是 `LINESTRING`，则返回 null。

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

以下 SQL 将四点 `LINESTRING` 的扩展的已知文本 (EWKT) 表示形式返回到 `GEOMETRY` 对象，并返回线串的起点。

```
SELECT ST_AsEWKT(ST_StartPoint(ST_GeomFromText('LINESTRING(0 0,10 0,10 10,5 5,0 5)',4326)));
```

```
st_asewkt
-------------
 SRID=4326;POINT(0 0)
```

# ST\$1Touches
<a name="ST_Touches-function"></a>

如果两个输入几何体的 2D 投影接触，则 ST\$1Touches 返回 true。如果两个几何体是非空的、相交并且没有共同的内部点，则它们是接触的。

## 语法
<a name="ST_Touches-function-syntax"></a>

```
ST_Touches(geom1, geom2)
```

## 参数
<a name="ST_Touches-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Touches-function-return"></a>

`BOOLEAN`

如果 *geom1* 或 *geom2* 为 null，则返回 null。

如果 *geom1* 和 *geom2* 不具有相同的空间参考系统标识符 (SRID) 值，则返回一个错误。

如果 *geom1* 或 *geom2* 为几何体集合，则返回一个错误。

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

以下 SQL 检查多边形是否与线串接触。

```
SELECT ST_Touches(ST_GeomFromText('POLYGON((0 0,10 0,0 10,0 0))'), ST_GeomFromText('LINESTRING(20 10,20 0,10 0)'));
```

```
 st_touches              
-------------
 t
```

# ST\$1Transform
<a name="ST_Transform-function"></a>

ST\$1Transform 返回一个新的几何体，坐标在由输入空间参考系统标识符 (SRID) 定义的空间参考系统中转换。

## 语法
<a name="ST_Transform-function-syntax"></a>

```
ST_Transform(geom, srid)
```

## 参数
<a name="ST_Transform-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *srid*   
一个 `INTEGER` 数据类型的值，该值表示一个 SRID。

## 返回类型
<a name="ST_Transform-function-return"></a>

`GEOMETRY`.

返回的几何体的 SRID 值将设置为 *srid*。

如果 *geom* 或 *srid* 为 null，则返回 null。

如果与输入 *geom* 关联的 SRID 值不存在，则返回错误。

如果 *srid* 不存在，则返回一个错误。

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

以下 SQL 转换空几何体集合的 SRID。

```
SELECT ST_AsEWKT(ST_Transform(ST_GeomFromText('GEOMETRYCOLLECTION EMPTY', 3857), 4326));
```

```
             st_asewkt
------------------------------------
 SRID=4326;GEOMETRYCOLLECTION EMPTY
```

以下 SQL 转换线串的 SRID。

```
SELECT ST_AsEWKT(ST_Transform(ST_GeomFromText('LINESTRING(110 40, 2 3, -10 80, -7 9, -22 -33)', 4326), 26918));
```

```
                                                                                            st_asewkt
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 SRID=26918;LINESTRING(73106.6977300955 15556182.9688576,14347201.5059964 1545178.32934967,1515090.41262989 9522193.25115316,10491250.83295 2575457.28410878,5672303.72135968 -5233682.61176205)
```

以下 SQL 转换多边形的 SRID。

```
SELECT ST_AsEWKT(ST_Transform(ST_GeomFromText('POLYGON Z ((-10 10 -7, -65 10 -6, -10 64 -5, -10 10 -7), (-11 11 5, -11 12 6, -12 11 7, -11 11 5))', 6989), 6317));
```

```
                                                                                                                                                                                                                      st_asewkt
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 SRID=6317;POLYGON Z ((6186430.2771091 -1090834.57212608 1100247.33216237,2654831.67853801 -5693304.90741276 1100247.50581055,2760987.41750022 -486836.575101877 5709710.44137268,6186430.2771091 -1090834.57212608 1100247.33216237),(6146675.25029258 -1194792.63532103 1209007.1115113,6125027.87562215 -1190584.81194058 1317403.77865723,6124888.99555252 -1301885.3455052 1209007.49312929,6146675.25029258 -1194792.63532103 1209007.1115113))
```

# ST\$1Union
<a name="ST_Union-function"></a>

ST\$1Union 返回一个表示两个几何体联合的几何体。也就是说，它合并输入几何体，以生成一个没有重叠的结果几何体。

## 语法
<a name="ST_Union-function-syntax"></a>

```
ST_Union(geom1, geom2)
```

## 参数
<a name="ST_Union-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Union-function-return"></a>

`GEOMETRY`

返回的几何体的空间参考系统标识符 (SRID) 值是输入几何体的 SRID 值。

如果 *geom1* 或 *geom2* 为 null，则返回 null。

如果 *geom1* 或 *geom2* 为空，则返回一个空的几何体。

如果 *geom1* 和 *geom2* 不具有相同的空间参考系统标识符 (SRID) 值，则返回一个错误。

如果 *geom1* 或 *geom2* 为几何体集合、线串或多线串，则返回一个错误。

如果 *geom1* 或 *geom2* 非二维 (2D) 几何体，则返回一个错误。

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

以下 SQL 返回表示两个输入几何体的联合的非空几何体。

```
SELECT ST_AsEWKT(ST_Union(ST_GeomFromText('POLYGON((0 0,100 100,0 200,0 0))'), ST_GeomFromText('POLYGON((0 0,10 0,0 10,0 0))')));
```

```
        st_asewkt        
-------------------------
 POLYGON((0 0,0 200,100 100,5 5,10 0,0 0))
```

# ST\$1Within
<a name="ST_Within-function"></a>

如果第一个输入几何体的 2D 投影在第二个输入几何体的 2D 投影中，则 ST\$1Within 返回 true。

例如，如果几何体 `A` 中的每个点均为几何体 `B` 中的一个点，并且其内部有非空相交区域，则几何体 `A` 在几何体 `B` 中。

ST\$1Within(`A`, `B`) 与 ST\$1Contains(`B`, `A`) 等效。

## 语法
<a name="ST_Within-function-syntax"></a>

```
ST_Within(geom1, geom2)
```

## 参数
<a name="ST_Within-function-arguments"></a>

 *geom1*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。此值将与 *geom2* 进行比较以确定它是否在 *geom2* 中。

 *geom2*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_Within-function-return"></a>

`BOOLEAN`

如果 *geom1* 或 *geom2* 为 null，则返回 null。

如果 *geom1* 和 *geom2* 不具有相同的空间参考系统标识符 (SRID) 值，则返回一个错误。

如果 *geom1* 或 *geom2* 为几何体集合，则返回一个错误。

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

以下 SQL 检查第一个多边形是否在第二个多边形中。

```
SELECT ST_Within(ST_GeomFromText('POLYGON((0 2,1 1,0 -1,0 2))'), ST_GeomFromText('POLYGON((-1 3,2 1,0 -3,-1 3))'));
```

```
st_within
-----------
 true
```

# ST\$1X
<a name="ST_X-function"></a>

ST\$1X 返回输入点的第一个坐标。

## 语法
<a name="ST_X-function-syntax"></a>

```
ST_X(point)
```

## 参数
<a name="ST_X-function-arguments"></a>

 *point*   
一个 `POINT` 数据类型的 `GEOMETRY` 值。

## 返回类型
<a name="ST_X-function-return"></a>

`DOUBLE PRECISION`第一个坐标的 值。

如果 *point* 为 null，则返回 null。

如果 *point* 是空点，则返回 null。

如果 *point* 不是 `POINT`，则返回一个错误。

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

以下 SQL 返回点的第一个坐标。

```
SELECT ST_X(ST_Point(1,2));
```

```
st_x
-----------
 1.0
```

# ST\$1XMax
<a name="ST_XMax-function"></a>

ST\$1XMax 返回输入几何体的最大的第一个坐标。

## 语法
<a name="ST_XMax-function-syntax"></a>

```
ST_XMax(geom)
```

## 参数
<a name="ST_XMax-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_XMax-function-return"></a>

`DOUBLE PRECISION`最大的第一个坐标的 值。

如果 *geom* 为空，则返回 null。

如果 *geom* 为 null，则返回 null。

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

以下 SQL 返回线串的最大的第一个坐标。

```
SELECT ST_XMax(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'));
```

```
st_xmax
-----------
 77.42
```

# ST\$1XMin
<a name="ST_XMin-function"></a>

ST\$1XMin 返回输入几何体的最小的第一个坐标。

## 语法
<a name="ST_XMin-function-syntax"></a>

```
ST_XMin(geom)
```

## 参数
<a name="ST_XMin-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_XMin-function-return"></a>

`DOUBLE PRECISION`最小的第一个坐标的 值。

如果 *geom* 为空，则返回 null。

如果 *geom* 为 null，则返回 null。

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

以下 SQL 返回线串的最小的第一个坐标。

```
SELECT ST_XMin(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'));
```

```
st_xmin
-----------
 77.27
```

# ST\$1Y
<a name="ST_Y-function"></a>

ST\$1Y 返回输入点的第二个坐标。

## 语法
<a name="ST_Y-function-syntax"></a>

```
ST_Y(point)
```

## 参数
<a name="ST_Y-function-arguments"></a>

 *point*   
一个 `POINT` 数据类型的 `GEOMETRY` 值。

## 返回类型
<a name="ST_Y-function-return"></a>

`DOUBLE PRECISION`第二个坐标的 值。

如果 *point* 为 null，则返回 null。

如果 *point* 是空点，则返回 null。

如果 *point* 不是 `POINT`，则返回一个错误。

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

以下 SQL 返回点的第二个坐标。

```
SELECT ST_Y(ST_Point(1,2));
```

```
st_y
-----------
 2.0
```

# ST\$1YMax
<a name="ST_YMax-function"></a>

ST\$1YMax 返回输入几何体的最大的第二个坐标。

## 语法
<a name="ST_YMax-function-syntax"></a>

```
ST_YMax(geom)
```

## 参数
<a name="ST_YMax-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_YMax-function-return"></a>

`DOUBLE PRECISION`最大的第二个坐标的 值。

如果 *geom* 为空，则返回 null。

如果 *geom* 为 null，则返回 null。

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

以下 SQL 返回线串的最大的第二个坐标。

```
SELECT ST_YMax(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'));
```

```
st_ymax
-----------
 29.31
```

# ST\$1YMin
<a name="ST_YMin-function"></a>

ST\$1YMin 返回输入几何体的最小的第二个坐标。

## 语法
<a name="ST_YMin-function-syntax"></a>

```
ST_YMin(geom)
```

## 参数
<a name="ST_YMin-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_YMin-function-return"></a>

`DOUBLE PRECISION`最小的第二个坐标的 值。

如果 *geom* 为空，则返回 null。

如果 *geom* 为 null，则返回 null。

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

以下 SQL 返回线串的最小的第二个坐标。

```
SELECT ST_YMin(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'));
```

```
st_ymin
-----------
 29.07
```

# ST\$1Z
<a name="ST_Z-function"></a>

ST\$1Z 返回输入点的 `z` 坐标。

## 语法
<a name="ST_Z-function-syntax"></a>

```
ST_Z(point)
```

## 参数
<a name="ST_Z-function-arguments"></a>

 *point*   
一个 `POINT` 数据类型的 `GEOMETRY` 值。

## 返回类型
<a name="ST_Z-function-return"></a>

`m` 坐标的 `DOUBLE PRECISION` 值。

如果 *point* 为 null，则返回 null。

如果 *point* 是 2D 或 3DM 点，则返回 null。

如果 *point* 是空点，则返回 null。

如果 *point* 不是 `POINT`，则返回一个错误。

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

以下 SQL 返回 3DZ 几何体中一个点的 `z` 坐标。

```
SELECT ST_Z(ST_GeomFromEWKT('POINT Z (1 2 3)'));
```

```
st_z
-----------
 3
```

以下 SQL 返回 4D 几何体中一个点的 `z` 坐标。

```
SELECT ST_Z(ST_GeomFromEWKT('POINT ZM (1 2 3 4)'));
```

```
st_z
-----------
 3
```

# ST\$1ZMax
<a name="ST_ZMax-function"></a>

ST\$1ZMax 返回输入几何体的最大的 `z` 坐标。

## 语法
<a name="ST_ZMax-function-syntax"></a>

```
ST_ZMax(geom)
```

## 参数
<a name="ST_ZMax-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_ZMax-function-return"></a>

最大的 `z` 坐标的 `DOUBLE PRECISION` 值。

如果 *geom* 为空，则返回 null。

如果 *geom* 为 null，则返回 null。

如果 *geom* 是 2D 或 3DM 几何体，则返回 null。

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

以下 SQL 返回 3DZ 几何体中一个线串的最大 `z` 坐标。

```
SELECT ST_ZMax(ST_GeomFromEWKT('LINESTRING Z (0 1 2, 3 4 5, 6 7 8)'));
```

```
st_zmax
-----------
  8
```

以下 SQL 返回 4D 几何体中一个线串的最大 `z` 坐标。

```
SELECT ST_ZMax(ST_GeomFromEWKT('LINESTRING ZM (0 1 2 3, 4 5 6 7, 8 9 10 11)'));
```

```
st_zmax
-----------
  10
```

# ST\$1ZMin
<a name="ST_ZMin-function"></a>

ST\$1ZMin 返回输入几何体的最小的 `z` 坐标。

## 语法
<a name="ST_ZMin-function-syntax"></a>

```
ST_ZMin(geom)
```

## 参数
<a name="ST_ZMin-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="ST_ZMin-function-return"></a>

最小 `z` 坐标的 `DOUBLE PRECISION` 值。

如果 *geom* 为空，则返回 null。

如果 *geom* 为 null，则返回 null。

如果 *geom* 是 2D 或 3DM 几何体，则返回 null。

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

以下 SQL 返回 3DZ 几何体中一个线串的最小 `z` 坐标。

```
SELECT ST_ZMin(ST_GeomFromEWKT('LINESTRING Z (0 1 2, 3 4 5, 6 7 8)'));
```

```
st_zmin
-----------
  2
```

以下 SQL 返回 4D 几何体中一个线串的最小 `z` 坐标。

```
SELECT ST_ZMin(ST_GeomFromEWKT('LINESTRING ZM (0 1 2 3, 4 5 6 7, 8 9 10 11)'));
```

```
st_zmin
-----------
  2
```

# SupportsBBox
<a name="SupportsBBox-function"></a>

如果输入几何体支持使用预先计算的边界框进行编码，则 SupportsBBox 返回 true。有关对边界框的支持的更多信息，请参阅[边界框](spatial-terminology.md#spatial-terminology-bounding-box)。

## 语法
<a name="SupportsBBox-function-syntax"></a>

```
SupportsBBox(geom)
```

## 参数
<a name="SupportsBBox-function-arguments"></a>

 *geom*   
一个 `GEOMETRY` 数据类型的值，或一个计算结果为 `GEOMETRY` 类型的表达式。

## 返回类型
<a name="SupportsBBox-function-return"></a>

`BOOLEAN`

如果 *geom* 为 null，则返回 null。

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

以下 SQL 返回 true，因为输入点几何体支持使用边界框进行编码。

```
SELECT SupportsBBox(AddBBox(ST_GeomFromText('POLYGON((0 0,1 0,0 1,0 0))')));
```

```
supportsbbox
--------------
t
```

以下 SQL 返回 false，因为输入点几何体不支持使用边界框编码。

```
SELECT SupportsBBox(DropBBox(ST_GeomFromText('POLYGON((0 0,1 0,0 1,0 0))')));
```

```
supportsbbox
--------------
f
```

# 字符串函数
<a name="String_functions_header"></a>

**Topics**
+ [\$1\$1（串联）运算符](r_concat_op.md)
+ [ASCII 函数](r_ASCII.md)
+ [BPCHARCMP 函数](r_BPCHARCMP.md)
+ [BTRIM 函数](r_BTRIM.md)
+ [BTTEXT\$1PATTERN\$1CMP 函数](r_BTTEXT_PATTERN_CMP.md)
+ [CHAR\$1LENGTH 函数](r_CHAR_LENGTH.md)
+ [CHARACTER\$1LENGTH 函数](r_CHARACTER_LENGTH.md)
+ [CHARINDEX 函数](r_CHARINDEX.md)
+ [CHR 函数](r_CHR.md)
+ [COLLATE 函数](r_COLLATE.md)
+ [CONCAT 函数](r_CONCAT.md)
+ [CRC32 函数](crc32-function.md)
+ [DIFFERENCE 函数](DIFFERENCE.md)
+ [INITCAP 函数](r_INITCAP.md)
+ [LEFT 和 RIGHT 函数](r_LEFT.md)
+ [LEN 函数](r_LEN.md)
+ [LENGTH 函数](r_LENGTH.md)
+ [LOWER 函数](r_LOWER.md)
+ [LPAD 和 RPAD 函数](r_LPAD.md)
+ [LTRIM 函数](r_LTRIM.md)
+ [OCTETINDEX 函数](OCTETINDEX.md)
+ [OCTET\$1LENGTH 函数](r_OCTET_LENGTH.md)
+ [POSITION 函数](r_POSITION.md)
+ [QUOTE\$1IDENT 函数](r_QUOTE_IDENT.md)
+ [QUOTE\$1LITERAL 函数](r_QUOTE_LITERAL.md)
+ [REGEXP\$1COUNT 函数](REGEXP_COUNT.md)
+ [REGEXP\$1INSTR 函数](REGEXP_INSTR.md)
+ [REGEXP\$1REPLACE 函数](REGEXP_REPLACE.md)
+ [REGEXP\$1SUBSTR 函数](REGEXP_SUBSTR.md)
+ [REPEAT 函数](r_REPEAT.md)
+ [REPLACE 函数](r_REPLACE.md)
+ [REPLICATE 函数](r_REPLICATE.md)
+ [REVERSE 函数](r_REVERSE.md)
+ [RTRIM 函数](r_RTRIM.md)
+ [SOUNDEX 函数](SOUNDEX.md)
+ [SPLIT\$1PART 函数](SPLIT_PART.md)
+ [STRPOS 函数](r_STRPOS.md)
+ [STRTOL 函数](r_STRTOL.md)
+ [SUBSTRING 函数](r_SUBSTRING.md)
+ [TEXTLEN 函数](r_TEXTLEN.md)
+ [TRANSLATE 函数](r_TRANSLATE.md)
+ [TRIM 函数](r_TRIM.md)
+ [UPPER 函数](r_UPPER.md)

字符串函数用于处理和操作字符串或计算结果为字符串的表达式。当这些函数中的 *string* 参数为文本值时，该参数必须括在单引号中。支持的数据类型包括 CHAR 和 VARCHAR。

以下部分提供了支持的函数的函数名称、语法和描述。对字符串的所有偏移都从 1 开始。
<a name="string-functions-deprecated"></a>
**弃用的仅领导节点函数**  
以下字符串函数因为仅在领导节点上运行而遭到弃用。有关更多信息，请参阅[仅领导节点函数](c_SQL_functions_leader_node_only.md)
+ GET\$1BYTE
+ SET\$1BIT
+ SET\$1BYTE
+ TO\$1ASCII

# \$1\$1（串联）运算符
<a name="r_concat_op"></a>

联接位于 `||` 符号的任意一侧的两个表达式并返回联接后的表达式。

与 [CONCAT 函数](r_CONCAT.md)相似。

**注意**  
如果一个表达式为 Null，或两个表达式都为 Null，则联接的结果为 `NULL`。

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

```
expression1 || expression2
```

## 参数
<a name="r_concat_op-arguments"></a>

 *expression1*   
`CHAR` 字符串、`VARCHAR` 字符串、二进制表达式或者其计算结果为这些类型之一的表达式。

 *expression2*   
`CHAR` 字符串、`VARCHAR` 字符串、二进制表达式或者其计算结果为这些类型之一的表达式。

## 返回类型
<a name="r_concat_op-return-type"></a>

 字符串的返回类型与输入参数的类型相同。例如，联接两个类型为 `VARCHAR` 的字符串会返回一个类型为 `VARCHAR` 的字符串。

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

 以下示例使用 TICKIT 示例数据库中的 USERS 表和 VENUE 表。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要联接示例数据库的 USERS 表中的 FIRSTNAME 和 LASTNAME 字段，请使用以下示例。

```
SELECT (firstname || ' ' || lastname) as fullname
FROM users
ORDER BY 1
LIMIT 10;

+-----------------+
|    fullname     |
+-----------------+
| Aaron Banks     |
| Aaron Booth     |
| Aaron Browning  |
| Aaron Burnett   |
| Aaron Casey     |
| Aaron Cash      |
| Aaron Castro    |
| Aaron Dickerson |
| Aaron Dixon     |
| Aaron Dotson    |
+-----------------+
```

 要联接可能包含 null 值的列，请使用 [NVL 和 COALESCE 函数](r_NVL_function.md) 表达式。以下示例使用 NVL 以在遇到 `NULL` 时返回 `0`。

```
SELECT (venuename || ' seats ' || NVL(venueseats, 0)) as seating
FROM venue
WHERE venuestate = 'NV' or venuestate = 'NC'
ORDER BY 1
LIMIT 10;

+-------------------------------------+
|               seating               |
+-------------------------------------+
| Ballys Hotel seats 0                |
| Bank of America Stadium seats 73298 |
| Bellagio Hotel seats 0              |
| Caesars Palace seats 0              |
| Harrahs Hotel seats 0               |
| Hilton Hotel seats 0                |
| Luxor Hotel seats 0                 |
| Mandalay Bay Hotel seats 0          |
| Mirage Hotel seats 0                |
| New York New York seats 0           |
+-------------------------------------+
```

# ASCII 函数
<a name="r_ASCII"></a>

ASCII 函数返回指定字符串中第一个字符的 ASCII 代码或 Unicode 代码点。如果字符串为空，该函数返回 `0`。如果字符串为 null，则返回 `NULL`。

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

```
ASCII('string')
```

## 参数
<a name="r_ASCII-arguments"></a>

 *string*   
`CHAR` 字符串或 `VARCHAR` 字符串。

## 返回类型
<a name="r_ASCII-return-type"></a>

 INTEGER 

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

要返回 `NULL`，请使用以下示例。如果两个参数相同，NULLIF 函数将返回 `NULL`，因此 ASCII 函数的输入参数为 `NULL`。有关更多信息，请参阅 [NULLIF 函数](r_NULLIF_function.md)。

```
SELECT ASCII(NULLIF('',''));

+-------+
| ascii |
+-------+
|  NULL |
+-------+
```

要返回 ASCII 代码 0，请使用以下示例。

```
SELECT ASCII('');

+-------+
| ascii |
+-------+
|     0 |
+-------+
```

要返回单词 amazon 的第一个字母的 ASCII 代码 97，请使用以下示例。

```
SELECT ASCII('amazon');

+-------+
| ascii |
+-------+
|    97 |
+-------+
```

要返回单词 Amazon 的第一个字母的 ASCII 代码 65，请使用以下示例。

```
SELECT ASCII('Amazon');

+-------+
| ascii |
+-------+
|    65 |
+-------+
```

# BPCHARCMP 函数
<a name="r_BPCHARCMP"></a>

比较两个字符串的值并返回整数。如果字符串相同，此函数返回 `0`。如果按字母顺序，第一个字符串更靠后，则函数返回 `1`。如果第二个字符串较大，则函数返回 `-1`。

对于多字节字符，该比较基于字节编码。

[BTTEXT\$1PATTERN\$1CMP 函数](r_BTTEXT_PATTERN_CMP.md)的同义词。

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

```
BPCHARCMP(string1, string2)
```

## 参数
<a name="r_BPCHARCMP-arguments"></a>

 *string1*   
`CHAR` 字符串或 `VARCHAR` 字符串。

 *string2*   
`CHAR` 字符串或 `VARCHAR` 字符串。

## 返回类型
<a name="r_BPCHARCMP-return-type"></a>

 INTEGER 

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

 以下示例使用 TICKIT 示例数据库中的 USERS 表。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要确定 USERS 表中前十个条目的用户的名字在字母顺序上是否比其姓氏更靠后，请使用以下示例。对于 FIRSTNAME 的字符串在字母顺序上比 LASTNAME 的字符串更靠后的条目，函数返回 `1`。如果 LASTNAME 在字母顺序上比 FIRSTNAME 更靠后，此函数将返回 `-1`。

```
SELECT userid, firstname, lastname, BPCHARCMP(firstname, lastname)
FROM users
ORDER BY 1, 2, 3, 4
LIMIT 10;

+--------+-----------+-----------+-----------+
| userid | firstname | lastname  | bpcharcmp |
+--------+-----------+-----------+-----------+
|      1 | Rafael    | Taylor    |        -1 |
|      2 | Vladimir  | Humphrey  |         1 |
|      3 | Lars      | Ratliff   |        -1 |
|      4 | Barry     | Roy       |        -1 |
|      5 | Reagan    | Hodge     |         1 |
|      6 | Victor    | Hernandez |         1 |
|      7 | Tamekah   | Juarez    |         1 |
|      8 | Colton    | Roy       |        -1 |
|      9 | Mufutau   | Watkins   |        -1 |
|     10 | Naida     | Calderon  |         1 |
+--------+-----------+-----------+-----------+
```

要返回 USERS 表中该函数返回 `0` 的所有条目，请使用以下示例。当 FIRSTNAME 与 LASTNAME 相同时，该函数返回 `0`。

```
SELECT userid, firstname, lastname,
BPCHARCMP(firstname, lastname)
FROM users 
WHERE BPCHARCMP(firstname, lastname)=0
ORDER BY 1, 2, 3, 4;

+--------+-----------+----------+-----------+
| userid | firstname | lastname | bpcharcmp |
+--------+-----------+----------+-----------+
|     62 | Chase     | Chase    |         0 |
|   4008 | Whitney   | Whitney  |         0 |
|  12516 | Graham    | Graham   |         0 |
|  13570 | Harper    | Harper   |         0 |
|  16712 | Cooper    | Cooper   |         0 |
|  18359 | Chase     | Chase    |         0 |
|  27530 | Bradley   | Bradley  |         0 |
|  31204 | Harding   | Harding  |         0 |
+--------+-----------+----------+-----------+
```

# BTRIM 函数
<a name="r_BTRIM"></a>

BTRIM 函数通过删除前导空格和尾随空格或删除与可选的指定字符串匹配的前导字符和尾随字符来剪裁字符串。

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

```
BTRIM(string [, trim_chars ] )
```

## 参数
<a name="r_BTRIM-arguments"></a>

 *string*   
要剪裁的输入 VARCHAR 字符串。

 *trim\$1chars*   
该 VARCHAR 字符串包含要匹配的字符。

## 返回类型
<a name="r_BTRIM-return-type"></a>

BTRIM 函数返回 VARCHAR 字符串。

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

以下示例从字符串 `' abc '` 中剪裁前导和尾随空格：

```
select '     abc    ' as untrim, btrim('     abc    ') as trim;

untrim    | trim
----------+------
   abc    | abc
```

以下示例从字符串 `'xyzaxyzbxyzcxyz'` 中删除前导和尾随 `'xyz'` 字符串。将删除前导和尾随的 `'xyz'`，但不会删除字符串内部的匹配字符。

```
select 'xyzaxyzbxyzcxyz' as untrim,
btrim('xyzaxyzbxyzcxyz', 'xyz') as trim;

     untrim      |   trim
-----------------+-----------
 xyzaxyzbxyzcxyz | axyzbxyzc
```

以下示例从字符串 `'setuphistorycassettes'` 中删除与 *trim\$1chars* 列表 `'tes'` 中的任何字符相匹配的开头和结尾部分。在输入字符串开头或结尾部分，在 *trim\$1chars* 列表中未包含的其他字符之前出现的任何 `t`、`e` 或 `s` 都将被删除。

```
SELECT btrim('setuphistorycassettes', 'tes');

     btrim      
-----------------
 uphistoryca
```

# BTTEXT\$1PATTERN\$1CMP 函数
<a name="r_BTTEXT_PATTERN_CMP"></a>

BPCHARCMP 函数的同义词。

有关更多信息，请参阅 [BPCHARCMP 函数](r_BPCHARCMP.md)。

# CHAR\$1LENGTH 函数
<a name="r_CHAR_LENGTH"></a>

LEN 函数的同义词。

请参阅 [LEN 函数](r_LEN.md)。

# CHARACTER\$1LENGTH 函数
<a name="r_CHARACTER_LENGTH"></a>

LEN 函数的同义词。

请参阅 [LEN 函数](r_LEN.md)。

# CHARINDEX 函数
<a name="r_CHARINDEX"></a>

返回指定子字符串在字符串中的位置。

有关类似的函数，请参阅[POSITION 函数](r_POSITION.md)和[STRPOS 函数](r_STRPOS.md)。

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

```
CHARINDEX( substring, string )
```

## 参数
<a name="charindex-arguments"></a>

 *substring*   
要在 *string* 中搜索的子字符串。

 *string*   
要搜索的字符串或列。

## 返回类型
<a name="charindex-return-type"></a>

 INTEGER   
CHARINDEX 函数返回与子字符串的位置对应的 `INTEGER`（从 1 开始，而不是从 0 开始）。此位置基于字符数而不是字节数，这是为了将多字节字符作为单字符计数。如果在字符串未找到子字符串，CHARINDEX 将返回 `0`。

## 示例
<a name="sub-charindex-usage-notes-examples"></a>

要显示字符串 `fish` 在单词 `dog` 中的位置，请使用以下示例。

```
SELECT CHARINDEX('fish', 'dog');

+-----------+
| charindex |
+-----------+
|         0 |
+-----------+
```

要显示字符串 `fish` 在单词 `dogfish` 中的位置，请使用以下示例。

```
SELECT CHARINDEX('fish', 'dogfish');

+-----------+
| charindex |
+-----------+
|         4 |
+-----------+
```

 以下示例使用 TICKIT 示例数据库中的 SALES 表。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要返回 SALES 表中佣金超过 999.00 的不同销售交易的数量，请使用以下示例。此命令通过检查小数点距离佣金值开头是否超过 4 位数来计算大于 999.00 的佣金。

```
SELECT DISTINCT CHARINDEX('.', commission), COUNT (CHARINDEX('.', commission))
FROM sales 
WHERE CHARINDEX('.', commission) > 4 
GROUP BY CHARINDEX('.', commission)
ORDER BY 1,2;

+-----------+-------+
| charindex | count |
+-----------+-------+
|         5 |   629 |
+-----------+-------+
```

# CHR 函数
<a name="r_CHR"></a>

CHR 函数返回与输入参数指定的 ASCII 码位值匹配的字符。

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

```
CHR(number)
```

## 参数
<a name="r_CHR-argument"></a>

 *number*   
输入参数是表示 ASCII 码位值的 `INTEGER`。

## 返回类型
<a name="r_CHR-return-type"></a>

 CHAR   
如果 ASCII 字符与输入值匹配，CHR 函数将返回 `CHAR` 字符串。如果输入数值没有匹配的 ASCII 字符，该函数将返回 `NULL`。

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

要返回与 ASCII 码位 0 对应的字符，请使用以下示例。请注意，对于输入 `0`，CHR 函数会返回 `NULL`。

```
SELECT CHR(0);

+-----+
| chr |
+-----+
|     |
+-----+
```

要返回与 ASCII 码位 65 对应的字符，请使用以下示例。

```
SELECT CHR(65);

+-----+
| chr |
+-----+
| A   |
+-----+
```

要返回以大写字母 A（ASCII 码位 65）开头的独特的事件名称，请使用以下示例。以下示例使用 TICKIT 示例数据库中的 EVENT 表。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

```
SELECT DISTINCT eventname FROM event
WHERE SUBSTRING(eventname, 1, 1)=CHR(65) LIMIT 5;

+-----------------------+
|       eventname       |
+-----------------------+
| A Catered Affair      |
| As You Like It        |
| A Man For All Seasons |
| Alan Jackson          |
| Armando Manzanero     |
+-----------------------+
```

# COLLATE 函数
<a name="r_COLLATE"></a>

COLLATE 函数覆盖字符串列或表达式的排序规则。

有关如何使用数据库排序规则创建表的信息，请参阅[CREATE TABLE](r_CREATE_TABLE_NEW.md)。

有关如何使用数据库排序规则创建数据库的信息，请参阅[CREATE DATABASE](r_CREATE_DATABASE.md)。

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

```
COLLATE( string, 'case_sensitive' | 'cs' | 'case_insensitive' | 'ci');
```

## 参数
<a name="r_COLLATE-argument"></a>

 *string*   
要覆盖的字符串列或表达式。

 *'case\$1sensitive'* \$1 *'cs'* \$1 *'case\$1insensitive'* \$1 *'ci'*  
排序规则名称的字符串常量。Amazon Redshift 对此参数仅支持以下值：  
+  *case\$1sensitive* 
+  *cs* 
+  *case\$1insensitive* 
+  *ci* 
*case\$1sensitive* 和 *cs* 可以互换，生成的结果相同。同样，*case\$1insensitive* 和 *ci* 可以互换，生成的结果相同。

## 返回类型
<a name="r_COLLATE-return-type"></a>

COLLATE 函数根据第一个输入表达式类型返回 `VARCHAR`、`CHAR` 或 `SUPER`。此函数仅更改第一个输入参数的排序规则，不会更改其输出值。

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

要创建表 T 并将表 T 中的 col1 定义为 `case_sensitive`，请使用以下示例。

```
CREATE TABLE T ( col1 Varchar(20) COLLATE case_sensitive );

INSERT INTO T VALUES ('john'),('JOHN');
```

 当您运行第一个查询时，Amazon Redshift 仅返回 `john`。在 col1 上运行 COLLATE 函数后，排序规则变成 `case_insensitive`。第二个查询同时返回 `john` 和 `JOHN`。

```
SELECT * FROM T WHERE col1 = 'john';

+------+
| col1 |
+------+
| john |
+------+

SELECT * FROM T WHERE COLLATE(col1, 'case_insensitive') = 'john';

+------+
| col1 |
+------+
| john |
| JOHN |
+------+
```

要创建表 A 并将表 A 中的 col1 定义为 `case_insensitive`，请使用以下示例。

```
CREATE TABLE A ( col1 Varchar(20) COLLATE case_insensitive );

INSERT INTO A VALUES ('john'),('JOHN');
```

 当您运行第一个查询时，Amazon Redshift 同时返回 `john` 和 `JOHN`。在 col1 上运行 COLLATE 函数后，排序规则变成 `case_sensitive`。第二个查询仅返回 `john`。

```
SELECT * FROM A WHERE col1 = 'john';

+------+
| col1 |
+------+
| john |
| JOHN |
+------+

SELECT * FROM A WHERE COLLATE(col1, 'case_sensitive') = 'john';

+------+
| col1 |
+------+
| john |
+------+
```

# CONCAT 函数
<a name="r_CONCAT"></a>

CONCAT 函数将联接两个表达式并返回生成的表达式。要联接两个以上的表达式，请使用嵌套 CONCAT 函数。在两个表达式之间使用联接运算符（`||`）将生成与 CONCAT 函数相同的结果。

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

```
CONCAT ( expression1, expression2 )
```

## 参数
<a name="r_CONCAT-arguments"></a>

 *expression1*、*expression2*   
两个参数可以是固定长度字符串、可变长度字符串、二进制表达式或计算结果为其中一个输入的表达式。

## 返回类型
<a name="r_CONCAT-return-type"></a>

 CONCAT 返回一个表达式。表达式的数据类型与输入参数的数据类型相同。

如果输入表达式的类型不同，Amazon Redshift 会尝试隐式转换其中一个表达式类型。如果值无法转换，则会返回一个错误。

## 使用说明
<a name="r_CONCAT-usage-notes"></a>
+ 对于 CONCAT 函数和联接运算符，如果一个或多个表达式为 null，则联接的结果也为 null。

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

以下示例联接两个字符文本：

```
SELECT CONCAT('December 25, ', '2008');

concat
-------------------
December 25, 2008
(1 row)
```

以下查询（使用 `||` 运算符而不是 CONCAT）将生成相同的结果：

```
SELECT 'December 25, '||'2008';

?column?
-------------------
December 25, 2008
(1 row)
```

以下示例使用一个 CONCAT 函数中的另一个嵌套 CONCAT 函数来串联三个字符串：

```
SELECT CONCAT('Thursday, ', CONCAT('December 25, ', '2008'));

concat
-----------------------------
Thursday, December 25, 2008
(1 row)
```

要串联可能包含 NULL 的列，请使用 [NVL 和 COALESCE 函数](r_NVL_function.md)，它会在遇到 NULL 时返回给定值。以下示例使用 NVL 在遇到 NULL 时返回 0。

```
SELECT CONCAT(venuename, CONCAT(' seats ', NVL(venueseats, 0))) AS seating
FROM venue WHERE venuestate = 'NV' OR venuestate = 'NC'
ORDER BY 1
LIMIT 5;

seating                            
-----------------------------------
Ballys Hotel seats 0               
Bank of America Stadium seats 73298
Bellagio Hotel seats 0             
Caesars Palace seats 0             
Harrahs Hotel seats 0              
(5 rows)
```

以下查询联接 VENUE 表中的 CITY 和 STATE 值：

```
SELECT CONCAT(venuecity, venuestate)
FROM venue
WHERE venueseats > 75000
ORDER BY venueseats;

concat
-------------------
DenverCO
Kansas CityMO
East RutherfordNJ
LandoverMD
(4 rows)
```

以下查询使用嵌套 CONCAT 函数。该查询将联接 VENUE 表中的 CITY 和 STATE 值，但会使用逗号和空格分隔生成的字符串：

```
SELECT CONCAT(CONCAT(venuecity,', '),venuestate)
FROM venue
WHERE venueseats > 75000
ORDER BY venueseats;

concat
---------------------
Denver, CO
Kansas City, MO
East Rutherford, NJ
Landover, MD
(4 rows)
```

以下示例联接了两个二进制表达式。其中 `abc` 是一个二进制值（具有一个 `616263` 的十六进制表示形式），`def` 是一个二进制值（具有一个 `646566` 的十六进制表示形式）。结果会自动显示为二进制值的十六进制表示形式。

```
SELECT CONCAT('abc'::VARBYTE, 'def'::VARBYTE);

concat
-------------------
616263646566
```

# CRC32 函数
<a name="crc32-function"></a>

CRC32 是一个用于错误检测的函数。此函数使用 CRC32 算法来检测源数据和目标数据之间的变化。CRC32 函数会将长度可变的字符串转换为以 32 位二进制序列的十六进制值的文本表示形式表示的 8 字符字符串。要检测源数据和目标数据之间的变化，请对源数据使用 CRC32 函数并存储输出。然后，对目标数据使用 CRC32 函数，并将该输出与来自源数据的输出进行比较。如果数据未经修改，则输出将相同；如果修改了数据，则输出将有所不同。

## 语法
<a name="crc32-function-syntax"></a>

```
CRC32(string)
```

## 参数
<a name="crc32-function-arguments"></a>

 *string*   
`CHAR` 字符串、`VARCHAR` 字符串或隐式计算为 `CHAR` 或 `VARCHAR` 类型的表达式。

## 返回类型
<a name="crc32-function-return-type"></a>

CRC32 函数返回以 32 位二进制序列的十六进制值的文本表示形式表示的 8 字符字符串。Amazon Redshift CRC32 函数基于 CRC-32C 多项式。

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

显示字符串 `Amazon Redshift` 的 8 位值。

```
SELECT CRC32('Amazon Redshift');

+----------+
|  crc32   |
+----------+
| f2726906 |
+----------+
```

# DIFFERENCE 函数
<a name="DIFFERENCE"></a>

DIFFERENCE 函数比较两个字符串的美国 Soundex 代码。该函数返回 `INTEGER`，以指示 Soundex 代码之间匹配的字符数。

 Soundex 代码是一个长度为四个字符的字符串。Soundex 代码表示单词的发音方式，而不是其拼写方式。例如，`Smith` 和 `Smyth` 具有相同的 Soundex 代码。

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

```
DIFFERENCE(string1, string2)
```

## 参数
<a name="DIFFERENCE-arguments"></a>

 *string1*   
`CHAR` 字符串、`VARCHAR` 字符串或隐式计算为 `CHAR` 或 `VARCHAR` 类型的表达式。

 *string2*   
`CHAR` 字符串、`VARCHAR` 字符串或隐式计算为 `CHAR` 或 `VARCHAR` 类型的表达式。

## 返回类型
<a name="DIFFERENCE-return-type"></a>

 INTEGER   
DIFFERENCE 函数返回 0–4 之间的一个 `INTEGER` 值，该值计算两个字符串的美国 Soundex 代码中匹配字符的数量。Soundex 代码具有 4 个字符，因此，当字符串的所有 4 个字符的美国 Soundex 代码值都相同时，DIFFERENCE 函数返回 `4`。如果两个字符串中有一个为空，则 DIFFERENCE 返回 `0`。如果两个字符串都不包含有效字符，则此函数返回 `1`。DIFFERENCE 函数仅转换英文字母小写或大写 ASCII 字符，包括 a–z 和 A–Z。DIFFERENCE 将忽略其他字符。

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

要比较字符串 `%` 和 `@` 的 Soundex 值，请使用以下示例。因为这两个字符串都不包含有效字符，所以此函数返回 `1`。

```
SELECT DIFFERENCE('%', '@');

+------------+
| difference |
+------------+
|          1 |
+------------+
```

要比较 `Amazon` 和一个空字符串的 Soundex 值，请使用以下示例。因为两个字符串中有一个是空的，所以该函数返回 `0`。

```
SELECT DIFFERENCE('Amazon', '');

+------------+
| difference |
+------------+
|          0 |
+------------+
```

要比较字符串 `Amazon` 和 `Ama` 的 Soundex 值，请使用以下示例。因为字符串的 Soundex 值中有 2 个字符是相同的，所以该函数返回 `2`。

```
SELECT DIFFERENCE('Amazon', 'Ama');

+------------+
| difference |
+------------+
|          2 |
+------------+
```

要比较字符串 `Amazon` 和 `+-*/%Amazon` 的 Soundex 值，请使用以下示例。因为字符串的 Soundex 值中所有 4 个字符都是相同的，所以该函数返回 `4`。请注意，该函数会忽略第二个字符串中的无效字符 `+-*/%`。

```
SELECT DIFFERENCE('Amazon', '+-*/%Amazon');

+------------+
| difference |
+------------+
|          4 |
+------------+
```

要比较字符串 `AC/DC` 和 `Ay See Dee See` 的 Soundex 值，请使用以下示例。因为字符串的 Soundex 值中所有 4 个字符都是相同的，所以该函数返回 `4`。

```
SELECT DIFFERENCE('AC/DC', 'Ay See Dee See');

+------------+
| difference |
+------------+
|          4 |
+------------+
```

# INITCAP 函数
<a name="r_INITCAP"></a>

将指定字符串中的每个单词的第一个字母大写。INITCAP 支持 UTF-8 多字节字符，并且每个字符最多可以有 4 个字节。

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

```
INITCAP(string)
```

## 参数
<a name="r_INITCAP-argument"></a>

 *string*   
`CHAR` 字符串、`VARCHAR` 字符串或隐式计算为 `CHAR` 或 `VARCHAR` 类型的表达式。

## 返回类型
<a name="r_INITCAP-return-type"></a>

VARCHAR

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

INITCAP 函数会将字符串中的每个单词的第一个字母大写，并将所有后续字母小写。因此，务必了解哪些字符（空格字符除外）充当分隔符。*文字分隔符* 字符是任何非字母数字字符，包括标点符号、普通符号和控制字符。所有以下字符都是文字分隔符：

```
! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ 
```

制表符、换行符、换页符和回车也是文字分隔符。

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

以下示例使用 TICKIT 示例数据库的 CATEGORY 表和 USERS 表中的数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要使 CATDESC 列中每个单词的首字母大写，请使用以下示例。

```
SELECT catid, catdesc, INITCAP(catdesc)
FROM category
ORDER BY 1, 2, 3;

+-------+--------------------------------------------+--------------------------------------------+
| catid |                  catdesc                   |                  initcap                   |
+-------+--------------------------------------------+--------------------------------------------+
|     1 | Major League Baseball                      | Major League Baseball                      |
|     2 | National Hockey League                     | National Hockey League                     |
|     3 | National Football League                   | National Football League                   |
|     4 | National Basketball Association            | National Basketball Association            |
|     5 | Major League Soccer                        | Major League Soccer                        |
|     6 | Musical theatre                            | Musical Theatre                            |
|     7 | All non-musical theatre                    | All Non-Musical Theatre                    |
|     8 | All opera and light opera                  | All Opera And Light Opera                  |
|     9 | All rock and pop music concerts            | All Rock And Pop Music Concerts            |
|    10 | All jazz singers and bands                 | All Jazz Singers And Bands                 |
|    11 | All symphony, concerto, and choir concerts | All Symphony, Concerto, And Choir Concerts |
+-------+--------------------------------------------+--------------------------------------------+
```

要显示在大写字符不作为单词的首字母时 INITCAP 函数不保留这些字符，请使用以下示例。例如，字符串 `MLB` 变成 `Mlb`。

```
SELECT INITCAP(catname)
FROM category
ORDER BY catname;

+-----------+
|  initcap  |
+-----------+
| Classical |
| Jazz      |
| Mlb       |
| Mls       |
| Musicals  |
| Nba       |
| Nfl       |
| Nhl       |
| Opera     |
| Plays     |
| Pop       |
+-----------+
```

要显示除空格以外的非字母数字字符用作单词分隔符，请使用以下示例。每个字符串中的几个字母将为大写。

```
SELECT email, INITCAP(email)
FROM users
ORDER BY userid DESC LIMIT 5;

+------------------------------------+------------------------------------+
|               email                |              initcap               |
+------------------------------------+------------------------------------+
| urna.Ut@egetdictumplacerat.edu     | Urna.Ut@Egetdictumplacerat.Edu     |
| nibh.enim@egestas.ca               | Nibh.Enim@Egestas.Ca               |
| in@Donecat.ca                      | In@Donecat.Ca                      |
| sodales@blanditviverraDonec.ca     | Sodales@Blanditviverradonec.Ca     |
| sociis.natoque.penatibus@vitae.org | Sociis.Natoque.Penatibus@Vitae.Org |
+------------------------------------+------------------------------------+
```

# LEFT 和 RIGHT 函数
<a name="r_LEFT"></a>

这些函数返回指定数量的位于字符串最左侧或最右侧的字符。

该数量基于字符数而不是字节数，这是为了将多字节字符作为单字符计数。

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

```
LEFT( string,  integer )

RIGHT( string,  integer )
```

## 参数
<a name="r_LEFT-arguments"></a>

 *string*   
`CHAR` 字符串、`VARCHAR` 字符串或任何计算为 `CHAR` 或 `VARCHAR` 字符串的表达式。

 *integer*   
一个正整数。

## 返回类型
<a name="r_LEFT-return-type"></a>

VARCHAR

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

以下示例使用 TICKIT 示例数据库的 EVENT 表中的数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要返回事件 ID 在 1000 和 1005 之间的事件名称中最左侧的 5 个字符和最右侧的 5 个字符，请使用以下示例。

```
SELECT eventid, eventname,
LEFT(eventname,5) AS left_5,
RIGHT(eventname,5) AS right_5
FROM event
WHERE eventid BETWEEN 1000 AND 1005
ORDER BY 1;

+---------+----------------+--------+---------+
| eventid |   eventname    | left_5 | right_5 |
+---------+----------------+--------+---------+
|    1000 | Gypsy          | Gypsy  | Gypsy   |
|    1001 | Chicago        | Chica  | icago   |
|    1002 | The King and I | The K  | and I   |
|    1003 | Pal Joey       | Pal J  | Joey    |
|    1004 | Grease         | Greas  | rease   |
|    1005 | Chicago        | Chica  | icago   |
+---------+----------------+--------+---------+
```

# LEN 函数
<a name="r_LEN"></a>

以字符数形式返回指定字符串的长度。

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

LEN 是 [LENGTH 函数](r_LENGTH.md)、[CHAR\$1LENGTH 函数](r_CHAR_LENGTH.md)、[CHARACTER\$1LENGTH 函数](r_CHARACTER_LENGTH.md)和 [TEXTLEN 函数](r_TEXTLEN.md)的同义词。

```
LEN(expression)
```

## 参数
<a name="r_LEN-argument"></a>

 *expression*   
`CHAR` 字符串、`VARCHAR` 字符串、`VARBYTE` 表达式或隐式计算为 `CHAR`、`VARCHAR` 或 `VARBYTE` 类型的表达式。

## 返回类型
<a name="r_LEN-return-type"></a>

 INTEGER   
LEN 函数返回一个整数，表示输入字符串中的字符的数量。  
如果输入的是字符串，LEN 函数将返回多字节字符串中的字符的实际数量，而不是字节的数量。例如，存储 3 个 4 字节中文字符需要 `VARCHAR(12)` 列。LEN 函数将对同一字符串返回 `3`。要获取字符串长度（以字节为单位），请使用 [OCTET\$1LENGTH](r_OCTET_LENGTH.md) 函数。

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

如果 *expression* 为 `CHAR` 字符串，则不计算尾随空格。

如果 *expression* 为 `VARCHAR` 字符串，则计算尾随空格。

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

要返回字符串 `français` 中的字节数和字符数，请使用以下示例。

```
SELECT OCTET_LENGTH('français'), 
LEN('français');

+--------------+-----+
| octet_length | len |
+--------------+-----+
|            9 |   8 |
+--------------+-----+
```

要在不使用 OCTET\$1LENGTH 函数的情况下返回字符串 `français` 中的字节数和字符数，请使用以下示例。有关更多信息，请参阅[CAST 函数](r_CAST_function.md)。

```
SELECT LEN(CAST('français' AS VARBYTE)) as bytes, LEN('français');

+-------+-----+
| bytes | len |
+-------+-----+
|     9 |   8 |
+-------+-----+
```

要返回字符串 `cat`（没有尾随空格）、`cat `（有三个尾随空格）、`cat `（有三个尾随空格，强制转换为长度为 6 的 `CHAR`）以及 `cat `（有三个尾随空格，强制转换为长度为 6 的 `VARCHAR`）中的字符数，请使用以下示例。请注意，该函数不计算 `CHAR` 字符串的尾随空格，但的确计算 `VARCHAR` 字符串的尾随空格。

```
SELECT LEN('cat'), LEN('cat   '), LEN(CAST('cat   ' AS CHAR(6))) AS len_char, LEN(CAST('cat   ' AS VARCHAR(6))) AS len_varchar;

+-----+-----+----------+-------------+
| len | len | len_char | len_varchar |
+-----+-----+----------+-------------+
|   3 |   6 |        3 |           6 |
+-----+-----+----------+-------------+
```

以下示例使用 TICKIT 示例数据库的 VENUE 表中的数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要返回 VENUE 表中最长的 10 个场地名称，请使用以下示例。

```
SELECT venuename, LEN(venuename)
FROM venue
ORDER BY 2 DESC, 1
LIMIT 10;

+-----------------------------------------+-----+
|                venuename                | len |
+-----------------------------------------+-----+
| Saratoga Springs Performing Arts Center |  39 |
| Lincoln Center for the Performing Arts  |  38 |
| Nassau Veterans Memorial Coliseum       |  33 |
| Jacksonville Municipal Stadium          |  30 |
| Rangers BallPark in Arlington           |  29 |
| University of Phoenix Stadium           |  29 |
| Circle in the Square Theatre            |  28 |
| Hubert H. Humphrey Metrodome            |  28 |
| Oriole Park at Camden Yards             |  27 |
| Dick's Sporting Goods Park              |  26 |
+-----------------------------------------+-----+
```

# LENGTH 函数
<a name="r_LENGTH"></a>

LEN 函数的同义词。

请参阅 [LEN 函数](r_LEN.md)。

# LOWER 函数
<a name="r_LOWER"></a>

将字符串转换为小写。LOWER 支持 UTF-8 多字节字符，并且每个字符最多可以有 4 个字节。

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

```
LOWER(string)
```

## 参数
<a name="r_LOWER-argument"></a>

 *string*   
`VARCHAR` 字符串或任何计算结果为 `VARCHAR` 类型的表达式。

## 返回类型
<a name="r_LOWER-return-type"></a>

 字符串   
LOWER 函数返回与输入字符串具有相同数据类型的字符串。例如，如果输入是 `CHAR` 字符串，该函数将返回 `CHAR` 字符串。

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

以下示例使用 TICKIT 示例数据库的 CATEGORY 表中的数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要将 CATNAME 列中的 `VARCHAR` 字符串转换为小写，请使用以下示例。

```
SELECT catname, LOWER(catname) FROM category ORDER BY 1,2;

+-----------+-----------+
|  catname  |   lower   |
+-----------+-----------+
| Classical | classical |
| Jazz      | jazz      |
| MLB       | mlb       |
| MLS       | mls       |
| Musicals  | musicals  |
| NBA       | nba       |
| NFL       | nfl       |
| NHL       | nhl       |
| Opera     | opera     |
| Plays     | plays     |
| Pop       | pop       |
+-----------+-----------+
```

# LPAD 和 RPAD 函数
<a name="r_LPAD"></a>

这些函数根据指定长度在字符串前面或后面追加字符。

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

```
LPAD(string1, length, [ string2 ])
```

```
RPAD(string1, length, [ string2 ])
```

## 参数
<a name="r_LPAD-arguments"></a>

 *string1*   
`CHAR` 字符串、`VARCHAR` 字符串或隐式计算为 `CHAR` 或 `VARCHAR` 类型的表达式。

 *length*   
一个用于定义函数结果的长度的整数。字符串的长度基于字符数而不是字节数，这是为了将多字节字符作为单字符计数。如果 *string1* 的长度超过指定长度，它将被截断（在右侧）。如果 *length* 为零或负数，则函数的结果将为空字符串。

 *string2*   
（可选）追加到 *string1* 前面或后面的一个或多个字符。如果未指定此参数，则使用空格。

## 返回类型
<a name="r_LPAD-return-type"></a>

VARCHAR

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

以下示例使用 TICKIT 示例数据库的 EVENT 表中的数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要将指定的一组事件名称截断到 20 个字符，并在短于此长度的名称前面追加空格，请使用以下示例。

```
SELECT LPAD(eventname, 20) FROM event
WHERE eventid BETWEEN 1 AND 5 ORDER BY 1;

+---------------------+
|         lpad        |
+---------------------+
|              Salome |
|        Il Trovatore |
|       Boris Godunov |
|     Gotterdammerung |
|La Cenerentola (Cind |
+-----------------------+
```

要将相同的一组事件名称截断到 20 个字符，并在短于此长度的名称后面追加 `0123456789`，请使用以下示例。

```
SELECT RPAD(eventname, 20,'0123456789') FROM event
WHERE eventid BETWEEN 1 AND 5 ORDER BY 1;

+----------------------+
|         rpad         |
+----------------------+
| Boris Godunov0123456 |
| Gotterdammerung01234 |
| Il Trovatore01234567 |
| La Cenerentola (Cind |
| Salome01234567890123 |
+----------------------+
```

# LTRIM 函数
<a name="r_LTRIM"></a>

从字符串的开头剪裁几个字符。删除只包含剪裁字符列表中的字符的最长字符串。当输入字符串中没有了剪裁字符时，剪裁即告完成。

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

```
LTRIM( string [, trim_chars] )
```

## 参数
<a name="r_LTRIM-arguments"></a>

 *string*   
要剪裁的字符串列、表达式或字符串文本。

 *trim\$1chars*   
表示要从 *string* 的开头剪裁的字符的字符串列、表达式或字符串文本。如果未指定，则使用空格作为剪裁字符。

## 返回类型
<a name="r_LTRIM-return-type"></a>

LTRIM 函数返回与输入*字符串*（CHAR 或 VARCHAR）具有相同数据类型的字符串。

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

以下示例从 `listime` 列中剪裁掉年份。字符串文本中的剪裁字符 `'2008-'` 表示要从左侧剪裁的字符。如果您使用剪裁字符 `'028-'`，则会获得相同的结果。

```
select listid, listtime, ltrim(listtime, '2008-')
from listing
order by 1, 2, 3
limit 10;            

listid |      listtime       |     ltrim
-------+---------------------+----------------
     1 | 2008-01-24 06:43:29 | 1-24 06:43:29
     2 | 2008-03-05 12:25:29 | 3-05 12:25:29
     3 | 2008-11-01 07:35:33 | 11-01 07:35:33
     4 | 2008-05-24 01:18:37 | 5-24 01:18:37
     5 | 2008-05-17 02:29:11 | 5-17 02:29:11
     6 | 2008-08-15 02:08:13 | 15 02:08:13
     7 | 2008-11-15 09:38:15 | 11-15 09:38:15
     8 | 2008-11-09 05:07:30 | 11-09 05:07:30
     9 | 2008-09-09 08:03:36 | 9-09 08:03:36
    10 | 2008-06-17 09:44:54 | 6-17 09:44:54
```

当 *trim\$1chars* 中的任意字符出现在 *string* 的开头时，LTRIM 都会予以删除。以下示例从 VENUENAME（VARCHAR 列）的开头剪裁字符“C”、“D”和“G”。

```
select venueid, venuename, ltrim(venuename, 'CDG')
from venue
where venuename like '%Park'
order by 2
limit 7;             

venueid | venuename                  | btrim                    
--------+----------------------------+--------------------------
    121 | ATT Park                   | ATT Park                
    109 | Citizens Bank Park         | itizens Bank Park        
    102 | Comerica Park              | omerica Park             
      9 | Dick's Sporting Goods Park | ick's Sporting Goods Park
     97 | Fenway Park                | Fenway Park              
    112 | Great American Ball Park   | reat American Ball Park  
    114 | Miller Park                | Miller Park
```

以下示例使用从 `venueid` 列中检索到的剪裁字符 `2`。

```
select ltrim('2008-01-24 06:43:29', venueid) 
from venue where venueid=2;              

ltrim
------------------
008-01-24 06:43:29
```

以下示例不剪裁任何字符，因为在 `'0'` 剪裁字符之前找到了 `2`。

```
select ltrim('2008-01-24 06:43:29', '0');              

ltrim
-------------------
2008-01-24 06:43:29
```

以下示例使用默认的空格剪裁字符，从字符串的开头剪裁掉两个空格。

```
select ltrim('  2008-01-24 06:43:29');              

ltrim
-------------------
2008-01-24 06:43:29
```

# OCTETINDEX 函数
<a name="OCTETINDEX"></a>

OCTETINDEX 函数以字节数形式返回子字符串在字符串中的位置。

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

```
OCTETINDEX(substring, string)
```

## 参数
<a name="OCTETINDEX-arguments"></a>

 *substring*   
`CHAR` 字符串、`VARCHAR` 字符串或隐式计算为 `CHAR` 或 `VARCHAR` 类型的表达式。

 *字符串*   
`CHAR` 字符串、`VARCHAR` 字符串或隐式计算为 `CHAR` 或 `VARCHAR` 类型的表达式。

## 返回类型
<a name="OCTETINDEX-return-type"></a>

 INTEGER   
OCTETINDEX 函数以字节数的形式返回一个 `INTEGER` 值，该值与 *substring* 在 *string* 中的位置相对应，其中 *string* 中的第一个字符被计数为 1。如果 *string* 不包含多字节字符，则结果等于 CHARINDEX 函数的结果。如果 *string* 不包含 *substring*，则该函数返回 `0`。如果 *substring* 为空，该函数返回 `1`。

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

要返回字符串 `Amazon Redshift` 中子字符串 `q` 的位置，请使用以下示例。因为 *substring* 不在 *string* 中，所以此示例返回 `0`。

```
SELECT OCTETINDEX('q', 'Amazon Redshift');

+------------+
| octetindex |
+------------+
|          0 |
+------------+
```

要返回空子字符串在字符串 `Amazon Redshift` 中的位置，请使用以下示例。因为 *substring* 为空，所以此示例返回 `1`。

```
SELECT OCTETINDEX('', 'Amazon Redshift');

+------------+
| octetindex |
+------------+
|          1 |
+------------+
```

要返回字符串 `Amazon Redshift` 中子字符串 `Redshift` 的位置，请使用以下示例。因为 *substring* 从 *string* 的第八个字节开始，所以此示例返回 `8`。

```
SELECT OCTETINDEX('Redshift', 'Amazon Redshift');

+------------+
| octetindex |
+------------+
|          8 |
+------------+
```

要返回字符串 `Amazon Redshift` 中子字符串 `Redshift` 的位置，请使用以下示例。因为 *string* 的前六个字符是双字节字符，所以此示例返回 `21`。

```
SELECT OCTETINDEX('Redshift', 'Άμαζον Amazon Redshift');

+------------+
| octetindex |
+------------+
|         21 |
+------------+
```

# OCTET\$1LENGTH 函数
<a name="r_OCTET_LENGTH"></a>

以字节数形式返回指定字符串的长度。

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

```
OCTET_LENGTH(expression)
```

## 参数
<a name="r_OCTET_LENGTH-argument"></a>

 *expression*   
`CHAR` 字符串、`VARCHAR` 字符串、`VARBYTE` 表达式或隐式计算为 `CHAR`、`VARCHAR` 或 `VARBYTE` 类型的表达式。

## 返回类型
<a name="r_OCTET_LENGTH-return-type"></a>

 INTEGER   
OCTET\$1LENGTH 函数返回一个整数，表示输入字符串中的字节数。  
如果输入的是字符串，[LEN](r_LEN.md) 函数将返回多字节字符串中字符的实际数量，而不是字节的数量。例如，存储 3 个 4 字节中文字符需要 `VARCHAR(12)` 列。OCTET\$1LENGTH 函数对于该字符串将返回 `12`，而 LEN 函数将对于该同一个字符串将返回 `3`。

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

如果 *expression* 是 `CHAR` 字符串，则此函数返回 `CHAR` 字符串的长度。例如，`CHAR(6)` 输入的输出为 `CHAR(6)`。

如果 *expression* 为 `VARCHAR` 字符串，则计算尾随空格。

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

当带有三个尾随空格的字符串 `francais` 强制转换为 `CHAR` 和 `VARCHAR` 类型时，要返回字节数，请使用以下示例。有关更多信息，请参阅[CAST 函数](r_CAST_function.md)。

```
SELECT OCTET_LENGTH(CAST('francais   ' AS CHAR(15))) AS octet_length_char, OCTET_LENGTH(CAST('francais   ' AS VARCHAR(15))) AS octet_length_varchar;

+-------------------+----------------------+
| octet_length_char | octet_length_varchar |
+-------------------+----------------------+
|                15 |                   11 |
+-------------------+----------------------+
```

要返回字符串 `français` 中的字节数和字符数，请使用以下示例。

```
SELECT OCTET_LENGTH('français'), LEN('français');

+--------------+-----+
| octet_length | len |
+--------------+-----+
|            9 |   8 |
+--------------+-----+
```

要在字符串 `français` 强制转换为 `VARBYTE` 时返回字节数，请使用以下示例。

```
SELECT OCTET_LENGTH(CAST('français' AS VARBYTE));

+--------------+
| octet_length |
+--------------+
|            9 |
+--------------+
```

# POSITION 函数
<a name="r_POSITION"></a>

返回指定子字符串在字符串中的位置。

有关类似的函数，请参阅[CHARINDEX 函数](r_CHARINDEX.md)和[STRPOS 函数](r_STRPOS.md)。

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

```
POSITION(substring IN string )
```

## 参数
<a name="r_POSITION-arguments"></a>

 *substring*   
要在 *string* 中搜索的子字符串。

 *string*   
要搜索的字符串或列。

## 返回类型
<a name="position-return-type"></a>

POSITION 函数返回与子字符串的位置对应的 `INTEGER`（从 1 开始，而不是从 0 开始）。此位置基于字符数而不是字节数，这是为了将多字节字符作为单字符计数。如果在字符串中未找到子字符串，POSITION 将返回 `0`。

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

要显示字符串 `fish` 在单词 `dog` 中的位置，请使用以下示例。

```
SELECT POSITION('fish' IN 'dog');

+-----------+
|  position |
+-----------+
|         0 |
+-----------+
```

要显示字符串 `fish` 在单词 `dogfish` 中的位置，请使用以下示例。

```
SELECT POSITION('fish' IN 'dogfish');

+-----------+
|  position |
+-----------+
|         4 |
+-----------+
```

 以下示例使用 TICKIT 示例数据库中的 SALES 表。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要返回 SALES 表中佣金超过 999.00 的不同销售交易的数量，请使用以下示例。此命令通过检查小数点距离佣金值开头是否超过 4 位数来计算大于 999.00 的佣金。

```
SELECT DISTINCT POSITION('.' IN commission), COUNT (POSITION('.' IN commission))
FROM sales 
WHERE POSITION('.' IN commission) > 4 
GROUP BY POSITION('.' IN commission)
ORDER BY 1,2;

+-----------+-------+
|  position | count |
+-----------+-------+
|         5 |   629 |
+-----------+-------+
```

# QUOTE\$1IDENT 函数
<a name="r_QUOTE_IDENT"></a>

QUOTE\$1IDENT 函数将指定的字符串作为一个带前导双引号和尾随双引号的字符串返回。此函数输出可用作 SQL 语句中的标识符。此函数适当地在任何嵌入式双引号之外再加上一对双引号。

QUOTE\$1IDENT 仅在需要时（当字符串包含非标识符字符或会转换为小写时）添加双引号，从而创建有效的标识符。要始终返回一个单引号字符串，请使用 [QUOTE\$1LITERAL](r_QUOTE_LITERAL.md)。

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

```
QUOTE_IDENT(string)
```

## 参数
<a name="r_QUOTE_IDENT-argument"></a>

 *string*   
`CHAR` 或 `VARCHAR` 字符串。

## 返回类型
<a name="r_QUOTE_IDENT-return-type"></a>

QUOTE\$1IDENT 函数返回与输入 *string* 相同类型的字符串。

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

要返回带双引号的字符串 `"CAT"`，请使用以下示例。

```
SELECT QUOTE_IDENT('"CAT"');

+-------------+
| quote_ident |
+-------------+
| """CAT"""   |
+-------------+
```

以下示例使用 TICKIT 示例数据库的 CATEGORY 表中的数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要返回用引号括起的 CATNAME 列，请使用以下示例。

```
SELECT catid, QUOTE_IDENT(catname)
FROM category
ORDER BY 1,2;

+-------+-------------+
| catid | quote_ident |
+-------+-------------+
|     1 | "MLB"       |
|     2 | "NHL"       |
|     3 | "NFL"       |
|     4 | "NBA"       |
|     5 | "MLS"       |
|     6 | "Musicals"  |
|     7 | "Plays"     |
|     8 | "Opera"     |
|     9 | "Pop"       |
|    10 | "Jazz"      |
|    11 | "Classical" |
+-------+-------------+
```

# QUOTE\$1LITERAL 函数
<a name="r_QUOTE_LITERAL"></a>

QUOTE\$1LITERAL 函数以单引号字符串的形式返回指定字符串，以便此字符串可用作 SQL 语句中的字符串文本。如果输入参数为数字，则 QUOTE\$1LITERAL 会将其视为字符串。请适当地在任何嵌入式单引号和反斜杠之外再加上一对双引号。

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

```
QUOTE_LITERAL(string)
```

## 参数
<a name="r_QUOTE_LITERAL-argument"></a>

 *string*   
`CHAR` 或 `VARCHAR` 字符串。

## 返回类型
<a name="r_QUOTE_LITERAL-return-type"></a>

QUOTE\$1LITERAL 函数返回与输入 *string* 相同数据类型的 `CHAR` 或 `VARCHAR` 字符串。

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

要返回带单引号的字符串 `''CAT''`，请使用以下示例。

```
SELECT QUOTE_LITERAL('''CAT''');

+---------------+
| quote_literal |
+---------------+
| '''CAT'''     |
+---------------+
```

以下示例使用 TICKIT 示例数据库的 CATEGORY 表中的数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要返回用单引号括起的 CATNAME 列，请使用以下示例。

```
SELECT catid, QUOTE_LITERAL(catname)
FROM category
ORDER BY 1,2;

+-------+---------------+
| catid | quote_literal |
+-------+---------------+
|     1 | 'MLB'         |
|     2 | 'NHL'         |
|     3 | 'NFL'         |
|     4 | 'NBA'         |
|     5 | 'MLS'         |
|     6 | 'Musicals'    |
|     7 | 'Plays'       |
|     8 | 'Opera'       |
|     9 | 'Pop'         |
|    10 | 'Jazz'        |
|    11 | 'Classical'   |
+-------+---------------+
```

要返回用单引号括起的 CATID 列，请使用以下示例。

```
SELECT QUOTE_LITERAL(catid), catname
FROM category
ORDER BY 1,2;

+---------------+-----------+
| quote_literal |  catname  |
+---------------+-----------+
| '1'           | MLB       |
| '10'          | Jazz      |
| '11'          | Classical |
| '2'           | NHL       |
| '3'           | NFL       |
| '4'           | NBA       |
| '5'           | MLS       |
| '6'           | Musicals  |
| '7'           | Plays     |
| '8'           | Opera     |
| '9'           | Pop       |
+---------------+-----------+
```

# REGEXP\$1COUNT 函数
<a name="REGEXP_COUNT"></a>

在字符串中搜索正则表达式模式，并返回指示指定模式在字符串中出现的次数的整数。如果未找到匹配项，此函数将返回 `0`。有关正则表达式的更多信息，请参阅 [POSIX 运算符](pattern-matching-conditions-posix.md)和 Wikipedia 中的 [Regular expression](https://en.wikipedia.org/wiki/Regular_expression)。

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

```
REGEXP_COUNT( source_string, pattern [, position [, parameters ] ] )
```

## 参数
<a name="REGEXP_COUNT-arguments"></a>

 *source\$1string*   
`CHAR` 或 `VARCHAR` 字符串。

 * 模式*   
表示正则表达式模式的 UTF-8 字符串文本。有关更多信息，请参阅 [POSIX 运算符](pattern-matching-conditions-posix.md)。

 *position*   
（可选）指示在 *source\$1string* 中开始搜索的位置的正 `INTEGER`。此位置基于字符数而不是字节数，这是为了将多字节字符作为单字符计数。默认值为 `1`。如果 *position* 小于 `1`，则搜索从 *source\$1string* 的第一个字符开始。如果 *position* 大于 *source\$1string* 中字符的数量，则结果为 `0`。

 *参数*   
（可选）一个或多个字符串文本，指示函数与模式的匹配方式。可能的值包括：  
+ c – 执行区分大小写的匹配。默认情况下，使用区分大小写的匹配。
+ i – 执行不区分大小写的匹配。
+ p – 使用 Perl 兼容正则表达式 (PCRE) 方言解释模式。有关 PCRE 的更多信息，请参阅 Wikipedia 中的 [Perl Compatible Regular Expressions](https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions)。

## 返回类型
<a name="REGEXP_COUNT-return-type"></a>

INTEGER

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

要计算三个字母序列出现的次数，请使用以下示例。

```
SELECT REGEXP_COUNT('abcdefghijklmnopqrstuvwxyz', '[a-z]{3}');

+--------------+
| regexp_count |
+--------------+
|            8 |
+--------------+
```

要使用不区分大小写的匹配计算字符串 `FOX` 的出现次数，请使用以下示例。

```
SELECT REGEXP_COUNT('the fox', 'FOX', 1, 'i');

+--------------+
| regexp_count |
+--------------+
|            1 |
+--------------+
```

要使用以 PCRE 方言编写的模式来定位至少包含一个数值和一个小写字母的单词，请使用以下示例。此示例使用 `?=` 运算符，它在 PCRE 中具有特定的前瞻含义。此示例使用区分大小写的匹配计算此类单词的出现次数。

```
SELECT REGEXP_COUNT('passwd7 plain A1234 a1234', '(?=[^ ]*[a-z])(?=[^ ]*[0-9])[^ ]+', 1, 'p');

+--------------+
| regexp_count |
+--------------+
|            2 |
+--------------+
```

要使用以 PCRE 方言编写的模式来定位至少包含一个数值和一个小写字母的单词，请使用以下示例。它使用 `?=` 运算符，它在 PCRE 中具有特定的含义。此示例计算此类单词的出现次数，但与前面的示例不同，因为它使用了不区分大小写的匹配。

```
SELECT REGEXP_COUNT('passwd7 plain A1234 a1234', '(?=[^ ]*[a-z])(?=[^ ]*[0-9])[^ ]+', 1, 'ip');

+--------------+
| regexp_count |
+--------------+
|            3 |
+--------------+
```

以下示例使用 TICKIT 示例数据库的 USERS 表中的数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要计算顶级域名为 `org` 或 `edu` 的次数，请使用以下示例。

```
SELECT email, REGEXP_COUNT(email,'@[^.]*\.(org|edu)') FROM users
ORDER BY userid LIMIT 4;

+-----------------------------------------------+--------------+
|                     email                     | regexp_count |
+-----------------------------------------------+--------------+
| Etiam.laoreet.libero@sodalesMaurisblandit.edu |            1 |
| Suspendisse.tristique@nonnisiAenean.edu       |            1 |
| amet.faucibus.ut@condimentumegetvolutpat.ca   |            0 |
| sed@lacusUtnec.ca                             |            0 |
+-----------------------------------------------+--------------+
```

# REGEXP\$1INSTR 函数
<a name="REGEXP_INSTR"></a>

在字符串中搜索正则表达式模式并返回指示匹配子字符串的开始位置的整数。如果未找到匹配项，此函数将返回 `0`。REGEXP\$1INSTR 与 [ 函数相似，只不过前者可让您在字符串中搜索正则表达式模式。](r_POSITION.md)有关正则表达式的更多信息，请参阅 [POSIX 运算符](pattern-matching-conditions-posix.md)和 Wikipedia 中的 [Regular expression](https://en.wikipedia.org/wiki/Regular_expression)。

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

```
REGEXP_INSTR( source_string, pattern [, position [, occurrence] [, option [, parameters ] ] ] ] )
```

## 参数
<a name="REGEXP_INSTR-arguments"></a>

 *source\$1string*   
要搜索的字符串表达式（如列名称）。

 *pattern*   
表示正则表达式模式的 UTF-8 字符串文本。有关更多信息，请参阅 [POSIX 运算符](pattern-matching-conditions-posix.md)。

 *position*   
（可选）指示在 *source\$1string* 中开始搜索的位置的正 `INTEGER`。此位置基于字符数而不是字节数，这是为了将多字节字符作为单字符计数。默认值为 `1`。如果 *position* 小于 `1`，则搜索从 *source\$1string* 的第一个字符开始。如果 *position* 大于 *source\$1string* 中字符的数量，则结果为 `0`。

 *出现*   
（可选）一个正 `INTEGER`，指示要使用的模式的哪一次出现。REGEXP\$1INSTR 会跳过第一个 `occurrence-1` 匹配项。默认值为 `1`。如果 *occurrence* 小于 `1` 或大于 *source\$1string* 中的字符数量，则会忽略搜索且结果为 `0`。

 *option*( )   
（可选）一个值，指示是返回匹配项的第一个字符的位置（`0`），还是匹配项结尾后面第一个字符的位置（`1`）。非零值与 `1` 相同。默认值为 `0`。

 *参数*   
（可选）一个或多个字符串文本，指示函数与模式的匹配方式。可能的值包括：  
+ c – 执行区分大小写的匹配。默认情况下，使用区分大小写的匹配。
+ i – 执行不区分大小写的匹配。
+ e – 使用子表达式提取子字符串。

  如果 *pattern* 包含一个子表达式，REGEXP\$1INSTR 会使用 *pattern* 中的第一个子表达式来匹配子字符串。REGEXP\$1INSTR 仅考虑第一个子表达式；其他子表达式会被忽略。如果模式没有子表达式，REGEXP\$1INSTR 会忽略“e”参数。
+ p – 使用 Perl 兼容正则表达式 (PCRE) 方言解释模式。有关 PCRE 的更多信息，请参阅 Wikipedia 中的 [Perl Compatible Regular Expressions](https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions)。

## 返回类型
<a name="REGEXP_INSTR-return-type"></a>

整数

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

以下示例使用 TICKIT 示例数据库的 USERS 表中的数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要搜索作为域名开头的 `@` 字符并返回第一个匹配项的开始位置，请使用以下示例。

```
SELECT email, REGEXP_INSTR(email, '@[^.]*')
FROM users
ORDER BY userid LIMIT 4;

+-----------------------------------------------+--------------+
|                     email                     | regexp_instr |
+-----------------------------------------------+--------------+
| Etiam.laoreet.libero@sodalesMaurisblandit.edu |           21 |
| Suspendisse.tristique@nonnisiAenean.edu       |           22 |
| amet.faucibus.ut@condimentumegetvolutpat.ca   |           17 |
| sed@lacusUtnec.ca                             |            4 |
+-----------------------------------------------+--------------+
```

要搜索单词 `Center` 的变体并返回第一个匹配项的开始位置，请使用以下示例。

```
SELECT venuename, REGEXP_INSTR(venuename,'[cC]ent(er|re)$')
FROM venue
WHERE REGEXP_INSTR(venuename,'[cC]ent(er|re)$') > 0
ORDER BY venueid LIMIT 4;

+-----------------------+--------------+
|       venuename       | regexp_instr |
+-----------------------+--------------+
| The Home Depot Center |           16 |
| Izod Center           |            6 |
| Wachovia Center       |           10 |
| Air Canada Centre     |           12 |
+-----------------------+--------------+
```

要使用不区分大小写的匹配逻辑找到字符串 `FOX` 第一次出现的起始位置，请使用以下示例。

```
SELECT REGEXP_INSTR('the fox', 'FOX', 1, 1, 0, 'i');

+--------------+
| regexp_instr |
+--------------+
|            5 |
+--------------+
```

要使用以 PCRE 方言编写的模式来定位至少包含一个数值和一个小写字母的单词，请使用以下示例。它使用 `?=` 运算符，它在 PCRE 中具有特定的前瞻含义。此示例查找第二个此类单词的起始位置。

```
SELECT REGEXP_INSTR('passwd7 plain A1234 a1234', '(?=[^ ]*[a-z])(?=[^ ]*[0-9])[^ ]+', 1, 2, 0, 'p');

+--------------+
| regexp_instr |
+--------------+
|           21 |
+--------------+
```

要使用以 PCRE 方言编写的模式来定位至少包含一个数值和一个小写字母的单词，请使用以下示例。它使用 `?=` 运算符，它在 PCRE 中具有特定的前瞻含义。本示例查找第二个此类单词的起始位置，但与前面的示例不同，因为它使用了不区分大小写的匹配。

```
SELECT REGEXP_INSTR('passwd7 plain A1234 a1234', '(?=[^ ]*[a-z])(?=[^ ]*[0-9])[^ ]+', 1, 2, 0, 'ip');

+--------------+
| regexp_instr |
+--------------+
|           15 |
+--------------+
```

# REGEXP\$1REPLACE 函数
<a name="REGEXP_REPLACE"></a>

在字符串中搜索正则表达式模式并将该模式的每个匹配项替换为指定字符串。REGEXP\$1REPLACE 与 [REPLACE 函数](r_REPLACE.md)相似，只不过前者可让您在字符串中搜索正则表达式模式。有关正则表达式的更多信息，请参阅 [POSIX 运算符](pattern-matching-conditions-posix.md)和 Wikipedia 中的 [Regular expression](https://en.wikipedia.org/wiki/Regular_expression)。

REGEXP\$1REPLACE 与 [TRANSLATE 函数](r_TRANSLATE.md)和 [REPLACE 函数](r_REPLACE.md)相似，只不过 TRANSLATE 进行多次单字符替换，REPLACE 一次性将整个字符串替换为其他字符串，而 REGEXP\$1REPLACE 可让您在字符串中搜索正则表达式模式。

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

```
REGEXP_REPLACE( source_string, pattern [, replace_string [ , position [, parameters ] ] ] )
```

## 参数
<a name="REGEXP_REPLACE-arguments"></a>

 *source\$1string*   
要搜索的 `CHAR` 或 `VARCHAR` 字符串表达式（如列名称）。

 * 模式*   
表示正则表达式模式的 UTF-8 字符串文本。有关更多信息，请参阅 [POSIX 运算符](pattern-matching-conditions-posix.md)。

*replace\$1string*  
（可选）将替换模式的每次出现的 `CHAR` 或 `VARCHAR` 字符串表达式（如列名称）。默认值是空字符串 ("")。

 *position*   
（可选）指示在 *source\$1string* 中开始搜索的位置的正整数。此位置基于字符数而不是字节数，这是为了将多字节字符作为单字符计数。默认值为 `1`。如果 *position* 小于 `1`，则搜索从 *source\$1string* 的第一个字符开始。如果 *position* 大于 *source\$1string* 中的字符数量，则结果为 *source\$1string*。

 *参数*   
（可选）一个或多个字符串文本，指示函数与模式的匹配方式。可能的值包括：  
+ c – 执行区分大小写的匹配。默认情况下，使用区分大小写的匹配。
+ i – 执行不区分大小写的匹配。
+ p – 使用 Perl 兼容正则表达式 (PCRE) 方言解释模式。有关 PCRE 的更多信息，请参阅 Wikipedia 中的 [Perl Compatible Regular Expressions](https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions)。

## 返回类型
<a name="REGEXP_REPLACE-return-type"></a>

VARCHAR

如果 *pattern* 或 *replace\$1string* 为 `NULL`，则返回 `NULL`。

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

要使用不区分大小写的匹配替换字符串 `FOX` 在值 `quick brown fox` 内的所有出现，请使用以下示例。

```
SELECT REGEXP_REPLACE('the fox', 'FOX', 'quick brown fox', 1, 'i');

+---------------------+
|   regexp_replace    |
+---------------------+
| the quick brown fox |
+---------------------+
```

以下示例使用用 PCRE 方言编写的模式来定位至少包含一个数字和一个小写字母的单词。它使用 `?=` 运算符，它在 PCRE 中具有特定的前瞻含义。要将此单词的每次出现替换为值 `[hidden]`，请使用以下示例。

```
SELECT REGEXP_REPLACE('passwd7 plain A1234 a1234', '(?=[^ ]*[a-z])(?=[^ ]*[0-9])[^ ]+', '[hidden]', 1, 'p');

+-------------------------------+
|        regexp_replace         |
+-------------------------------+
| [hidden] plain A1234 [hidden] |
+-------------------------------+
```

以下示例使用用 PCRE 方言编写的模式来定位至少包含一个数字和一个小写字母的单词。它使用 `?=` 运算符，它在 PCRE 中具有特定的前瞻含义。要将此单词的每次出现替换为值 `[hidden]`，但与前面的示例不同，它使用不区分大小写的匹配，请使用以下示例。

```
SELECT REGEXP_REPLACE('passwd7 plain A1234 a1234', '(?=[^ ]*[a-z])(?=[^ ]*[0-9])[^ ]+', '[hidden]', 1, 'ip');

+----------------------------------+
|          regexp_replace          |
+----------------------------------+
| [hidden] plain [hidden] [hidden] |
+----------------------------------+
```

以下示例使用 TICKIT 示例数据库的 USERS 表中的数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要删除电子邮件地址中的 `@` 和域名，请使用以下示例。

```
SELECT email, REGEXP_REPLACE(email, '@.*\\.(org|gov|com|edu|ca)$')
FROM users
ORDER BY userid LIMIT 4;

+-----------------------------------------------+-----------------------+
|                     email                     |    regexp_replace     |
+-----------------------------------------------+-----------------------+
| Etiam.laoreet.libero@sodalesMaurisblandit.edu | Etiam.laoreet.libero  |
| Suspendisse.tristique@nonnisiAenean.edu       | Suspendisse.tristique |
| amet.faucibus.ut@condimentumegetvolutpat.ca   | amet.faucibus.ut      |
| sed@lacusUtnec.ca                             | sed                   |
+-----------------------------------------------+-----------------------+
```

要使用 `internal.company.com` 替换电子邮件地址的域名，请使用以下示例。

```
SELECT email, REGEXP_REPLACE(email, '@.*\\.[[:alpha:]]{2,3}','@internal.company.com') 
FROM users
ORDER BY userid LIMIT 4;

+-----------------------------------------------+--------------------------------------------+
|                     email                     |               regexp_replace               |
+-----------------------------------------------+--------------------------------------------+
| Etiam.laoreet.libero@sodalesMaurisblandit.edu | Etiam.laoreet.libero@internal.company.com  |
| Suspendisse.tristique@nonnisiAenean.edu       | Suspendisse.tristique@internal.company.com |
| amet.faucibus.ut@condimentumegetvolutpat.ca   | amet.faucibus.ut@internal.company.com      |
| sed@lacusUtnec.ca                             | sed@internal.company.com                   |
+-----------------------------------------------+--------------------------------------------+
```

# REGEXP\$1SUBSTR 函数
<a name="REGEXP_SUBSTR"></a>

通过在字符串中搜索正则表达式模式，返回字符串中的字符。REGEXP\$1SUBSTR 与 [SUBSTRING 函数](r_SUBSTRING.md) 函数相似，只不过前者可让您在字符串中搜索正则表达式模式。如果函数无法将正则表达式与字符串中的任何字符匹配，则返回一个空字符串。有关正则表达式的更多信息，请参阅 [POSIX 运算符](pattern-matching-conditions-posix.md)和 Wikipedia 中的 [Regular expression](https://en.wikipedia.org/wiki/Regular_expression)。

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

```
REGEXP_SUBSTR( source_string, pattern [, position [, occurrence [, parameters ] ] ] )
```

## 参数
<a name="REGEXP_SUBSTR-arguments"></a>

 *source\$1string*   
要搜索的字符串表达式。

 * 模式*   
表示正则表达式模式的 UTF-8 字符串文本。有关更多信息，请参阅 [POSIX 运算符](pattern-matching-conditions-posix.md)。

 *position*   
指示在 *source\$1string* 中开始搜索的位置的正整数。此位置基于字符数而不是字节数，这是为了将多字节字符作为单字符计数。默认值为 1。如果 *position* 小于 1，则搜索从 *source\$1string* 的第一个字符开始。如果 *position* 大于 *source\$1string* 中的字符数量，则结果为空字符串 ("")。

 *出现*   
一个正整数，指示要使用的模式的匹配项。REGEXP\$1SUBSTR 会跳过第一个 *occurrence* -1 匹配项。默认值是 1。如果 *occurrence* 小于 1 或大于 *source\$1string* 中的字符串，则会忽略搜索，并且结果为空。

 *参数*   
一个或多个字符串，指示函数与模式的匹配方式。可能的值包括：  
+ c – 执行区分大小写的匹配。默认情况下，使用区分大小写的匹配。
+ i – 执行不区分大小写的匹配。
+ e – 使用子表达式提取子字符串。

   如果 *pattern* 包含一个子表达式，REGEXP\$1SUBSTR 会使用 *pattern* 中的第一个子表达式来匹配子字符串。子表达式是模式中用括号括起的表达式。例如，模式 `'This is a (\\w+)'` 将第一个表达式与字符串 `'This is a '` 后接一个字词进行匹配。此时不返回*模式*，带 `e` 参数的 REGEXP\$1SUBSTR 仅返回子表达式内的字符串。

  REGEXP\$1SUBSTR 仅考虑第一个子表达式；其他子表达式会被忽略。如果模式没有子表达式，REGEXP\$1SUBSTR 会忽略“e”参数。
+ p – 使用 Perl 兼容正则表达式 (PCRE) 方言解释模式。有关 PCRE 的更多信息，请参阅 Wikipedia 中的 [Perl Compatible Regular Expressions](https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions)。

## 返回类型
<a name="REGEXP_SUBSTR-return-type"></a>

VARCHAR

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

以下示例返回电子邮件地址中 @ 字符和域扩展名之间的部分。所查询的 `users` 数据来自 Amazon Redshift 示例数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

```
SELECT email, regexp_substr(email,'@[^.]*')
FROM users
ORDER BY userid LIMIT 4;

                     email                     |      regexp_substr
-----------------------------------------------+--------------------------
 Suspendisse.tristique@nonnisiAenean.edu       | @nonnisiAenean
 amet.faucibus.ut@condimentumegetvolutpat.ca   | @condimentumegetvolutpat
 sed@lacusUtnec.ca                             | @lacusUtnec
 Cum@accumsan.com                              | @accumsan
```

以下示例使用不区分大小写的匹配返回与字符串 `FOX` 的第一次出现相对应的输入部分。

```
SELECT regexp_substr('the fox', 'FOX', 1, 1, 'i');

 regexp_substr
---------------
 fox
```

以下示例使用不区分大小写的匹配返回与字符串 `FOX` 的第二次出现相对应的输入部分。结果为空（非 null，长度为 0），因为没有第二次出现。

```
SELECT regexp_substr('the fox', 'FOX', 1, 2, 'i');

 regexp_substr
---------------
```

以下示例返回以小写字母开头的输入的第一部分。这在功能上与不带 `c` 参数的同一 SELECT 语句相同。

```
SELECT regexp_substr('THE SECRET CODE IS THE LOWERCASE PART OF 1931abc0EZ.', '[a-z]+', 1, 1, 'c');

 regexp_substr
---------------
 abc
```

以下示例使用用 PCRE 方言编写的模式来定位至少包含一个数字和一个小写字母的单词。它使用 `?=` 运算符，它在 PCRE 中具有特定的前瞻含义。此示例返回与第二个此类单词相对应的输入部分。

```
SELECT regexp_substr('passwd7 plain A1234 a1234', '(?=[^ ]*[a-z])(?=[^ ]*[0-9])[^ ]+', 1, 2, 'p');

 regexp_substr
---------------
 a1234
```

以下示例使用用 PCRE 方言编写的模式来定位至少包含一个数字和一个小写字母的单词。它使用 `?=` 运算符，它在 PCRE 中具有特定的前瞻含义。此示例返回与第二个此类单词相对应的输入部分，但与前面的示例不同，因为它使用了不区分大小写的匹配。

```
SELECT regexp_substr('passwd7 plain A1234 a1234', '(?=[^ ]*[a-z])(?=[^ ]*[0-9])[^ ]+', 1, 2, 'ip');

 regexp_substr
---------------
 A1234
```

以下示例使用子表达式，通过不区分大小写的匹配来查找与模式 `'this is a (\\w+)'` 匹配的第二个字符串。它返回括号内的子表达式。

```
SELECT regexp_substr(
               'This is a cat, this is a dog. This is a mouse.',
               'this is a (\\w+)', 1, 2, 'ie');
           
 regexp_substr
---------------
 dog
```

# REPEAT 函数
<a name="r_REPEAT"></a>

将字符串重复指定的次数。如果输入参数为数字，REPEAT 会将其视为字符串。

[REPLICATE 函数](r_REPLICATE.md)的同义词。

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

```
REPEAT(string, integer)
```

## 参数
<a name="r_REPEAT-arguments"></a>

 *string*   
第一个输入参数是要重复的字符串。

 *integer*   
第二个参数是指示字符串重复次数的 `INTEGER`。

## 返回类型
<a name="r_REPEAT-return-type"></a>

VARCHAR

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

以下示例使用 TICKIT 示例数据库的 CATEGORY 表中的数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要重复 CATEGORY 表中 CATID 列的值三次，请使用以下示例。

```
SELECT catid, REPEAT(catid,3)
FROM category
ORDER BY 1,2;

+-------+--------+
| catid | repeat |
+-------+--------+
|     1 |    111 |
|     2 |    222 |
|     3 |    333 |
|     4 |    444 |
|     5 |    555 |
|     6 |    666 |
|     7 |    777 |
|     8 |    888 |
|     9 |    999 |
|    10 | 101010 |
|    11 | 111111 |
+-------+--------+
```

以下示例演示如何生成最多 1600 万个字节的字符串：

```
SELECT 
    LEN(REPEAT('X', 5000000)) AS five_million_bytes,
    LEN(REPEAT('Y', 16000000)) AS sixteen_million_bytes;

 five_million_bytes  | sixteen_million_bytes
----------+-----------
 5000000  | 16000000
```

# REPLACE 函数
<a name="r_REPLACE"></a>

将现有字符串中一组字符的所有匹配项替换为其他指定字符。

REPLACE 与 [TRANSLATE 函数](r_TRANSLATE.md)和 [REGEXP\$1REPLACE 函数](REGEXP_REPLACE.md)相似，只不过 TRANSLATE 进行多次单字符替换，REGEXP\$1REPLACE 可让您在字符串中搜索正则表达式模式，而 REPLACE 一次性将整个字符串替换为其他字符串。

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

```
REPLACE(string, old_chars, new_chars)
```

## 参数
<a name="r_REPLACE-arguments"></a>

 *string*   
要搜索的 `CHAR` 或 `VARCHAR` 字符串 

 *old\$1chars*   
要替换的 `CHAR` 或 `VARCHAR` 字符串。

 *new\$1chars*   
用于替换 *old\$1string* 的新 `CHAR` 或 `VARCHAR` 字符串。

## 返回类型
<a name="r_REPLACE-return-type"></a>

VARCHAR  
如果 *old\$1chars* 或 *new\$1chars* 为 `NULL`，则将返回 `NULL`。

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

以下示例使用 TICKIT 示例数据库的 CATEGORY 表中的数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要将 CATGROUP 字段中的字符串 `Shows` 转换为 `Theatre`，请使用以下示例。

```
SELECT catid, catgroup, REPLACE(catgroup, 'Shows', 'Theatre')
FROM category
ORDER BY 1,2,3;

+-------+----------+----------+
| catid | catgroup | replace  |
+-------+----------+----------+
|     1 | Sports   | Sports   |
|     2 | Sports   | Sports   |
|     3 | Sports   | Sports   |
|     4 | Sports   | Sports   |
|     5 | Sports   | Sports   |
|     6 | Shows    | Theatre  |
|     7 | Shows    | Theatre  |
|     8 | Shows    | Theatre  |
|     9 | Concerts | Concerts |
|    10 | Concerts | Concerts |
|    11 | Concerts | Concerts |
+-------+----------+----------+
```

# REPLICATE 函数
<a name="r_REPLICATE"></a>

REPEAT 函数的同义词。

请参阅 [REPEAT 函数](r_REPEAT.md)。

# REVERSE 函数
<a name="r_REVERSE"></a>

REVERSE 函数对字符串运行并以反向顺序返回字符。例如，`reverse('abcde')` 将返回 `edcba`。此函数适用于数字和日期数据类型以及字符数据类型；但在大多数情况下，它对于字符串具有实用价值。

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

```
REVERSE( expression )
```

## 参数
<a name="r_REVERSE-argument"></a>

 *expression*   
一个表达式，带有表示字符反转目标的字符、日期、时间戳或数字数据类型。所有表达式都隐式转换为 `VARCHAR` 字符串。`CHAR` 字符串中的尾部空白会被忽略：

## 返回类型
<a name="r_REVERSE-return-type"></a>

VARCHAR

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

以下示例使用 TICKIT 示例数据库的 USERS 表和 SALES 表中的数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要从 USERS 表中选择 5 个不同的城市名称及其对应的反转名称，请使用以下示例。

```
SELECT DISTINCT city AS cityname, REVERSE(cityname)
FROM users 
ORDER BY city LIMIT 5;

+----------+----------+
| cityname | reverse  |
+----------+----------+
| Aberdeen | needrebA |
| Abilene  | enelibA  |
| Ada      | adA      |
| Agat     | tagA     |
| Agawam   | mawagA   |
+----------+----------+
```

要选择 5 个销售 ID 及其对应的反转 ID（已强制转换为字符串），请使用以下示例。

```
SELECT salesid, REVERSE(salesid)
FROM sales 
ORDER BY salesid DESC LIMIT 5;

+---------+---------+
| salesid | reverse |
+---------+---------+
|  172456 |  654271 |
|  172455 |  554271 |
|  172454 |  454271 |
|  172453 |  354271 |
|  172452 |  254271 |
+---------+---------+
```

# RTRIM 函数
<a name="r_RTRIM"></a>

RTRIM 函数从字符串的末尾剪裁指定的一组字符。删除只包含剪裁字符列表中的字符的最长字符串。当输入字符串中没有了剪裁字符时，剪裁即告完成。

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

```
RTRIM( string, trim_chars )
```

## 参数
<a name="r_RTRIM-arguments"></a>

 *string*   
要剪裁的字符串列、表达式或字符串文本。

 *trim\$1chars*   
表示要从 *string* 的结尾剪裁的字符的字符串列、表达式或字符串文本。如果未指定，则使用空格作为剪裁字符。

## 返回类型
<a name="r_RTRIM-return-type"></a>

与 *string* 参数具有相同的数据类型的字符串。

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

以下示例从字符串 `' abc '` 中剪裁前导和尾随空格：

```
select '     abc    ' as untrim, rtrim('     abc    ') as trim;

untrim    | trim
----------+------
   abc    |    abc
```

以下示例从字符串 `'xyzaxyzbxyzcxyz'` 中删除尾随字符串 `'xyz'`。将删除尾随的 `'xyz'`，但不会删除字符串内部的匹配字符。

```
select 'xyzaxyzbxyzcxyz' as untrim,
rtrim('xyzaxyzbxyzcxyz', 'xyz') as trim;

     untrim      |   trim
-----------------+-----------
 xyzaxyzbxyzcxyz | xyzaxyzbxyzc
```

以下示例从字符串 `'setuphistorycassettes'` 中删除与 *trim\$1chars* 列表 `'tes'` 中的任何字符相匹配的结尾部分。在输入字符串结尾部分，在 *trim\$1chars* 列表中未包含的其他字符之前出现的任何 `t`、`e` 或 `s` 都将被删除。

```
SELECT rtrim('setuphistorycassettes', 'tes');

     rtrim      
-----------------
 setuphistoryca
```

以下示例从 VENUENAME 的末尾剪裁字符“Park”（如果有）：

```
select venueid, venuename, rtrim(venuename, 'Park')
from venue
order by 1, 2, 3
limit 10;

venueid |         venuename          |          rtrim
--------+----------------------------+-------------------------
      1 | Toyota Park                | Toyota
      2 | Columbus Crew Stadium      | Columbus Crew Stadium
      3 | RFK Stadium                | RFK Stadium
      4 | CommunityAmerica Ballpark  | CommunityAmerica Ballp
      5 | Gillette Stadium           | Gillette Stadium
      6 | New York Giants Stadium    | New York Giants Stadium
      7 | BMO Field                  | BMO Field
      8 | The Home Depot Center      | The Home Depot Cente
      9 | Dick's Sporting Goods Park | Dick's Sporting Goods
     10 | Pizza Hut Park             | Pizza Hut
```

请注意，当字符 `P`、`a`、`r` 或 `k` 中的任意一个出现在 VENUENAME 的末尾时，RTRIM 都会予以删除。

# SOUNDEX 函数
<a name="SOUNDEX"></a>

SOUNDEX 函数返回美国 Soundex 值，其中包括输入字符串的第一个字母，后跟一个 3 位数字的声音编码，该编码表示您指定的字符串的英语发音。例如，`Smith` 和 `Smyth` 具有相同的 Soundex 值。

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

```
SOUNDEX(string)
```

## 参数
<a name="SOUNDEX-arguments"></a>

 *string*   
您可以指定要转换为美国 Soundex 代码值的 `CHAR` 或 `VARCHAR` 字符串。

## 返回类型
<a name="SOUNDEX-return-type"></a>

VARCHAR(4)

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

SOUNDEX 函数仅转换英文字母小写或大写 ASCII 字符，包括 a–z 和 A–Z。SOUNDEX 将忽略其他字符。对于由空格分隔的多个单词组成的字符串，SOUNDEX 返回单个 Soundex 值。

```
SELECT SOUNDEX('AWS Amazon');
            
+---------+
| soundex |
+---------+
| A252    |
+---------+
```

如果输入字符串不包含任何英文字母，SOUNDEX 将返回一个空字符串。

```
SELECT SOUNDEX('+-*/%');

+---------+
| soundex |
+---------+
|         |
+---------+
```

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

要返回 `Amazon` 的 Soundex 值，请使用以下示例。

```
SELECT SOUNDEX('Amazon');

+---------+
| soundex |
+---------+
| A525    |
+---------+
```

要返回 `smith` 和 `smyth` 的 Soundex 值，请使用以下示例。请注意，Soundex 值是相同的。

```
SELECT SOUNDEX('smith'), SOUNDEX('smyth');

+-------+-------+
| smith | smyth |
+-------+-------+
| S530  | S530  |
+-------+-------+
```

# SPLIT\$1PART 函数
<a name="SPLIT_PART"></a>

用指定的分隔符拆分字符串，并返回指定位置的部分内容。

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

```
SPLIT_PART(string, delimiter, position)
```

## 参数
<a name="SPLIT_PART-arguments"></a>

 *string*   
要拆分的字符串列、表达式或字符串文本。字符串可以是 CHAR 或 VARCHAR。

 *分隔符*   
分隔符字符串指示输入 *string* 的部分。  
如果 *delimiter* 是文本，则将其括在单引号中。

 *position*   
要返回的 *string* 部分的位置（从 1 算起）。必须是大于 0 的整数。如果 *position* 大于字符串部分的数量，SPLIT\$1PART 将返回空字符串。如果在*字符串*中未找到*分隔符*，则返回的值包含指定部分的内容，它可能是整个*字符串*或一个空值。

## 返回类型
<a name="SPLIT_PART-return-type"></a>

CHAR 或 VARCHAR 字符串，与 *string* 参数相同。

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

以下示例使用 `$` 分隔符，将字符串文本拆分为多个部分，并返回第二部分。

```
select split_part('abc$def$ghi','$',2)

split_part
----------
def
```

以下示例使用 `$` 分隔符，将字符串文本拆分为多个部分。它返回一个空字符串，因为找不到部分 `4`。

```
select split_part('abc$def$ghi','$',4)

split_part
----------
```

以下示例使用 `#` 分隔符，将字符串文本拆分为多个部分。它返回整个字符串，也就是第一部分，因为找不到分隔符。

```
select split_part('abc$def$ghi','#',1)

split_part
------------
abc$def$ghi
```

以下示例将时间戳字段 LISTTIME 拆分为年、月和日组成部分。

```
select listtime, split_part(listtime,'-',1) as year,
split_part(listtime,'-',2) as month, 
split_part(split_part(listtime,'-',3),' ',1) as day 
from listing limit 5;

      listtime       | year | month | day
---------------------+------+-------+------
 2008-03-05 12:25:29 | 2008 | 03    | 05
 2008-09-09 08:03:36 | 2008 | 09    | 09
 2008-09-26 05:43:12 | 2008 | 09    | 26
 2008-10-04 02:00:30 | 2008 | 10    | 04
 2008-01-06 08:33:11 | 2008 | 01    | 06
```

以下示例选择 LISTTIME 时间戳字段并在 `'-'` 字符处拆分它以获取月（LISTTIME 字符串的第二部分），然后计算每个月的条目数：

```
select split_part(listtime,'-',2) as month, count(*)
from listing
group by split_part(listtime,'-',2)
order by 1, 2;

 month | count
-------+-------
    01 | 18543
    02 | 16620
    03 | 17594
    04 | 16822
    05 | 17618
    06 | 17158
    07 | 17626
    08 | 17881
    09 | 17378
    10 | 17756
    11 | 12912
    12 | 4589
```

# STRPOS 函数
<a name="r_STRPOS"></a>

返回子字符串在指定字符串中的位置。

有关类似的函数，请参阅[CHARINDEX 函数](r_CHARINDEX.md)和[POSITION 函数](r_POSITION.md)。

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

```
STRPOS(string, substring )
```

## 参数
<a name="r_STRPOS-arguments"></a>

 *string*   
第一个输入参数是要在其中进行搜索的 `CHAR` 或 `VARCHAR` 字符串。

 *substring*   
第二个参数是要在 *string* 中搜索的子字符串。

## 返回类型
<a name="r_STRPOS-return-type"></a>

INTEGER  
STRPOS 函数返回与 *substring* 的位置对应的 `INTEGER`（从 1 开始，而不是从 0 开始）。此位置基于字符数而不是字节数，这是为了将多字节字符作为单字符计数。

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

如果在 *string* 中未找到 *substring*，STRPOS 将返回 `0`。

```
SELECT STRPOS('dogfish', 'fist');

+--------+
| strpos |
+--------+
|      0 |
+--------+
```

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

要显示 `fish` 在 `dogfish` 内的位置，请使用以下示例。

```
SELECT STRPOS('dogfish', 'fish');

+--------+
| strpos |
+--------+
|      4 |
+--------+
```

以下示例使用 TICKIT 示例数据库的 SALES 表中的数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要返回 SALES 表中 COMMISSION 超过 999.00 的销售交易的数量，请使用以下示例。

```
SELECT DISTINCT STRPOS(commission, '.'),
COUNT (STRPOS(commission, '.'))
FROM sales
WHERE STRPOS(commission, '.') > 4
GROUP BY STRPOS(commission, '.')
ORDER BY 1, 2;

+--------+-------+
| strpos | count |
+--------+-------+
|      5 |   629 |
+--------+-------+
```

# STRTOL 函数
<a name="r_STRTOL"></a>

将由一些指定基数组成的字符串表达式转换为等效的整数值。已转换的值必须在有符号 64 位范围中。

## 语法
<a name="r_STRTOL-syntax"></a>

```
STRTOL(num_string, base)
```

## 参数
<a name="r_STRTOL-arguments"></a>

 *num\$1string*   
要转换的数字的字符串表达式。如果 *num\$1string* 为空（`''`）或以 null 字符（`'\0'`）开头，则转换后的值为 `0`。如果 *num\$1string* 是包含 NULL 值的列，STRTOL 将返回 `NULL`。字符串能够以任意数量的空格开头，也可以后跟加号“`+`”或减号“`-`”以表示正负。默认值为“`+`”。如果 *base* 为 `16`，则字符串可以“`0x`”开头。

*base*  
`INTEGER` 介于 2 和 36 之间。

## 返回类型
<a name="r_STRTOL-return-type"></a>

BIGINT  
如果 *num\$1string* 为 null，则函数返回 `NULL`。

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

要将字符串和基数值对转换为整数，请使用以下示例。

```
SELECT STRTOL('0xf',16);

+--------+
| strtol |
+--------+
|     15 |
+--------+

SELECT STRTOL('abcd1234',16);

+------------+
|   strtol   |
+------------+
| 2882343476 |
+------------+

SELECT STRTOL('1234567', 10);

+---------+
| strtol  |
+---------+
| 1234567 |
+---------+

SELECT STRTOL('1234567', 8);

+--------+
| strtol |
+--------+
| 342391 |
+--------+

SELECT STRTOL('110101', 2);

+--------+
| strtol |
+--------+
|     53 |
+--------+

SELECT STRTOL('\0', 2);

+--------+
| strtol |
+--------+
|      0 |
+--------+
```

# SUBSTRING 函数
<a name="r_SUBSTRING"></a>

按指定的开始位置返回子字符串子集。

如果输入的是字符串，字符的开始位置和数量基于字符数而不是字节数，这是为了将多字节字符作为单个字符计数。如果输入的是二进制表达式，则开始位置和提取的子字符串基于字节。您无法指定负长度，但可指定负开始位置。

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

```
SUBSTRING(character_string FROM start_position [ FOR number_characters ] )
```

```
SUBSTRING(character_string, start_position, number_characters )
```

```
SUBSTRING(binary_expression, start_byte, number_bytes )
```

```
SUBSTRING(binary_expression, start_byte )
```

## 参数
<a name="r_SUBSTRING-arguments"></a>

 *character\$1string*   
要搜索的字符串。非字符数据类型将视为字符串。

 *start\$1position*   
字符串中开始提取的位置，从 1 开始。*start\$1position* 基于字符数而不是字节数，这是为了将多字节字符作为单个字符计数。此数字可以为负。

 *number\$1characters*   
要提取的字符的数量（子字符串的长度）。*number\$1characters* 基于字符数而不是字节数，这是为了将多字节字符作为单个字符计数。此数字不能为负。

 *binary\$1expression*   
要搜索的数据类型为 VARBYTE 的 binary\$1expression。

 *start\$1byte*   
二进制表达式中开始提取的位置，从 1 开始。此数字可以为负。

 *number\$1bytes*   
要提取的字节的数量（子字符串的长度）。此数字不能为负。

## 返回类型
<a name="r_SUBSTRING-return-type"></a>

根据输入选择 VARCHAR 或 VARBYTE。

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

以下是一些示例，说明如何使用 *start\$1position* 和 *number\$1characters* 从字符串的不同位置提取子字符串。

以下示例返回以第 6 个字符开头的 4 字符字符串。

```
select substring('caterpillar',6,4);
substring
-----------
pill
(1 row)
```

如果 *start\$1position* \$1 *number\$1characters* 超过 *string* 的长度，SUBSTRING 将返回从 *start\$1position* 开始到此字符串末尾的子字符串。例如：

```
select substring('caterpillar',6,8);
substring
-----------
pillar
(1 row)
```

如果 `start_position` 为负或 0，SUBSTRING 函数将返回从长度为 `start_position` \$1 `number_characters` -1 的字符串的第一个字符开始的子字符串。例如：

```
select substring('caterpillar',-2,6);
substring
-----------
cat
(1 row)
```

如果 `start_position` \$1 `number_characters` -1 小于或等于零，SUBSTRING 将返回空字符串。例如：

```
select substring('caterpillar',-5,4);
substring
-----------

(1 row)
```

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

以下示例返回 LISTING 表的 LISTTIME 字符串中的月份：

```
select listid, listtime,
substring(listtime, 6, 2) as month
from listing
order by 1, 2, 3
limit 10;

 listid |      listtime       | month
--------+---------------------+-------
      1 | 2008-01-24 06:43:29 | 01
      2 | 2008-03-05 12:25:29 | 03
      3 | 2008-11-01 07:35:33 | 11
      4 | 2008-05-24 01:18:37 | 05
      5 | 2008-05-17 02:29:11 | 05
      6 | 2008-08-15 02:08:13 | 08
      7 | 2008-11-15 09:38:15 | 11
      8 | 2008-11-09 05:07:30 | 11
      9 | 2008-09-09 08:03:36 | 09
     10 | 2008-06-17 09:44:54 | 06
(10 rows)
```

以下示例与上述示例相同，但使用 FROM...FOR 选项：

```
select listid, listtime,
substring(listtime from 6 for 2) as month
from listing
order by 1, 2, 3
limit 10;

 listid |      listtime       | month
--------+---------------------+-------
      1 | 2008-01-24 06:43:29 | 01
      2 | 2008-03-05 12:25:29 | 03
      3 | 2008-11-01 07:35:33 | 11
      4 | 2008-05-24 01:18:37 | 05
      5 | 2008-05-17 02:29:11 | 05
      6 | 2008-08-15 02:08:13 | 08
      7 | 2008-11-15 09:38:15 | 11
      8 | 2008-11-09 05:07:30 | 11
      9 | 2008-09-09 08:03:36 | 09
     10 | 2008-06-17 09:44:54 | 06
(10 rows)
```

您无法使用 SUBSTRING 以可预测的方式提取可能包含多字节字符的字符串的前缀，因为您需要根据字节数（而不是字符数）指定多字节字符串的长度。要基于以字节为单位的长度提取字符串的开始部分，您可将字符串强制转换为 VARCHAR(*byte\$1length*) 以截断字符串，其中 *byte\$1length* 是必需长度。以下示例提取字符串 `'Fourscore and seven'` 的前 5 个字节。

```
select cast('Fourscore and seven' as varchar(5));

varchar
-------
Fours
```

以下示例显示了二进制值 `abc` 的负开始位置。由于开始位置为 -3，所以子字符串从二进制值的开头进行提取。结果会自动显示为二进制子字符串的十六进制表示形式。

```
select substring('abc'::varbyte, -3);

 substring
-----------
 616263
```

以下示例显示二进制值 `abc` 的开始位置为 1。因为没有指定长度，所以将字符串从字符串开始位置提取到末尾。结果会自动显示为二进制子字符串的十六进制表示形式。

```
select substring('abc'::varbyte, 1);

 substring
-----------
 616263
```

以下示例显示二进制值 `abc` 的开始位置为 3。因为没有指定长度，所以将字符串从字符串开始位置提取到末尾。结果会自动显示为二进制子字符串的十六进制表示形式。

```
select substring('abc'::varbyte, 3);

 substring
-----------
 63
```

以下示例显示二进制值 `abc` 的开始位置为 2。字符串从开始位置提取到位置 10，但字符串的末尾位于位置 3。结果会自动显示为二进制子字符串的十六进制表示形式。

```
select substring('abc'::varbyte, 2, 10);

 substring
-----------
 6263
```

以下示例显示二进制值 `abc` 的开始位置为 2。字符串从开始位置提取 1 个字节。结果会自动显示为二进制子字符串的十六进制表示形式。

```
select substring('abc'::varbyte, 2, 1);

 substring
-----------
 62
```

以下示例返回出现在输入字符串 `Silva, Ana` 中最后一个空格之后的名字 `Ana`。

```
select reverse(substring(reverse('Silva, Ana'), 1, position(' ' IN reverse('Silva, Ana'))))

 reverse
-----------
 Ana
```

# TEXTLEN 函数
<a name="r_TEXTLEN"></a>

LEN 函数的同义词。

请参阅 [LEN 函数](r_LEN.md)。

# TRANSLATE 函数
<a name="r_TRANSLATE"></a>

对于给定表达式，将指定字符的所有匹配项替换为指定替代项。现有字符将按其在 *characters\$1to\$1replace* 和 *characters\$1to\$1substitute* 参数中的位置映射到替换字符。如果在 *characters\$1to\$1replace* 参数中指定的字符多于在 *characters\$1to\$1substitute* 参数中指定的字符，返回值中将省略 *characters\$1to\$1replace* 参数中的额外字符。

TRANSLATE 与 [REPLACE 函数](r_REPLACE.md)和 [REGEXP\$1REPLACE 函数](REGEXP_REPLACE.md)相似，只不过 REPLACE 将整个字符串替换为其他字符串，REGEXP\$1REPLACE 可让您在字符串中搜索正则表达式模式，而 TRANSLATE 进行多次单字符替换。

如果任何参数为 null，则返回 `NULL`。

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

```
TRANSLATE( expression, characters_to_replace, characters_to_substitute )
```

## 参数
<a name="r_TRANSLATE-arguments"></a>

 *expression*   
要转换的表达式。

 *characters\$1to\$1replace*   
一个包含要替换的字符的字符串。

 *characters\$1to\$1substitute*   
一个字符串，其中包含要替换其他字符的字符。

## 返回类型
<a name="r_TRANSLATE-return-type"></a>

VARCHAR

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

要替换字符串中的多个字符，请使用以下示例。

```
SELECT TRANSLATE('mint tea', 'inea', 'osin');

+-----------+
| translate |
+-----------+
| most tin  |
+-----------+
```

以下示例使用 TICKIT 示例数据库的 USERS 表中的数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要将列中所有值的 at（@）符号替换为句点，请使用以下示例。

```
SELECT email, TRANSLATE(email, '@', '.') as obfuscated_email
FROM users LIMIT 10;

+---------------------------------------+---------------------------------------+
|                 email                 |           obfuscated_email            |
+---------------------------------------+---------------------------------------+
| Cum@accumsan.com                      | Cum.accumsan.com                      |
| lorem.ipsum@Vestibulumante.com        | lorem.ipsum.Vestibulumante.com        |
| non.justo.Proin@ametconsectetuer.edu  | non.justo.Proin.ametconsectetuer.edu  |
| non.ante.bibendum@porttitortellus.org | non.ante.bibendum.porttitortellus.org |
| eros@blanditatnisi.org                | eros.blanditatnisi.org                |
| augue@Donec.ca                        | augue.Donec.ca                        |
| cursus@pedeacurna.edu                 | cursus.pedeacurna.edu                 |
| at@Duis.com                           | at.Duis.com                           |
| quam@facilisisvitaeorci.ca            | quam.facilisisvitaeorci.ca            |
| mi.lorem@nunc.edu                     | mi.lorem.nunc.edu                     |
+---------------------------------------+---------------------------------------+
```

 要将空格替换为下划线并去掉列中所有值的句点，请使用以下示例。

```
SELECT city, TRANSLATE(city, ' .', '_') 
FROM users
WHERE city LIKE 'Sain%' OR city LIKE 'St%'
GROUP BY city
ORDER BY city;

+----------------+---------------+
|      city      |   translate   |
+----------------+---------------+
| Saint Albans   | Saint_Albans  |
| Saint Cloud    | Saint_Cloud   |
| Saint Joseph   | Saint_Joseph  |
| Saint Louis    | Saint_Louis   |
| Saint Paul     | Saint_Paul    |
| St. George     | St_George     |
| St. Marys      | St_Marys      |
| St. Petersburg | St_Petersburg |
| Stafford       | Stafford      |
| Stamford       | Stamford      |
| Stanton        | Stanton       |
| Starkville     | Starkville    |
| Statesboro     | Statesboro    |
| Staunton       | Staunton      |
| Steubenville   | Steubenville  |
| Stevens Point  | Stevens_Point |
| Stillwater     | Stillwater    |
| Stockton       | Stockton      |
| Sturgis        | Sturgis       |
+----------------+---------------+
```

# TRIM 函数
<a name="r_TRIM"></a>

通过空白或指定的字符来剪裁字符串。

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

```
TRIM( [ BOTH | LEADING | TRAILING ] [trim_chars FROM ] string )
```

## 参数
<a name="r_TRIM-arguments"></a>

 BOTH \$1 LEADING \$1 TRAILING   
（可选）指定从何处剪裁字符。使用 BOTH 会删除前导和尾随字符，使用 LEADING 仅删除前导字符，使用 TRAILING 仅删除尾随字符。如果省略此参数，则会同时剪裁前导字符和尾随字符。

 *trim\$1chars*   
（可选）要从字符串剪裁的字符数。如果忽略此参数，则剪裁空白区域。

 *string*   
要剪裁的字符串。

## 返回类型
<a name="r_TRIM-return-type"></a>

TRIM 函数返回 `VARCHAR` 或 `CHAR` 字符串。如果您将 TRIM 函数与 SQL 命令结合使用，Amazon Redshift 会将结果隐式转换为 `VARCHAR`。如果您在 SQL 函数的 SELECT 列表中使用 TRIM 函数，Amazon Redshift 不会隐式转换结果，您可能需要执行显式转换以避免数据类型不匹配错误。有关显式转换的信息，请参阅 [CAST 函数](r_CAST_function.md)和 [CONVERT 函数](r_CONVERT_function.md) 函数。

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

要从字符串 ` dog ` 中剪裁前导和尾随空格，请使用以下示例。

```
SELECT TRIM('    dog    ');

+-------+
| btrim |
+-------+
| dog   |
+-------+
```

要从字符串 ` dog ` 中剪裁前导和尾随空格，请使用以下示例。

```
SELECT TRIM(BOTH FROM '    dog    ');

+-------+
| btrim |
+-------+
| dog   |
+-------+
```

要从字符串 `"dog"` 中删除前导双引号，请使用以下示例。

```
SELECT TRIM(LEADING '"' FROM'"dog"');

+-------+
| ltrim |
+-------+
| dog"  |
+-------+
```

要从字符串 `"dog"` 中删除尾随双引号，请使用以下示例。

```
SELECT TRIM(TRAILING '"' FROM'"dog"');

+-------+
| rtrim |
+-------+
| "dog  |
+-------+
```

当 *trim\$1chars* 中的任意字符出现在 *string* 的开头或结尾时，TRIM 都会予以删除。以下示例在字符“C”、“D”和“G”出现在 VENUENAME（即 `VARCHAR` 列）的开头或结尾时对其进行剪裁。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

```
SELECT venueid, venuename, TRIM('CDG' FROM venuename)
FROM venue
WHERE venuename LIKE '%Park'
ORDER BY 2
LIMIT 7;

+---------+----------------------------+---------------------------+
| venueid |         venuename          |           btrim           |
+---------+----------------------------+---------------------------+
|     121 | AT&T Park                  | AT&T Park                 |
|     109 | Citizens Bank Park         | itizens Bank Park         |
|     102 | Comerica Park              | omerica Park              |
|       9 | Dick's Sporting Goods Park | ick's Sporting Goods Park |
|      97 | Fenway Park                | Fenway Park               |
|     112 | Great American Ball Park   | reat American Ball Park   |
|     114 | Miller Park                | Miller Park               |
+---------+----------------------------+---------------------------+
```

# UPPER 函数
<a name="r_UPPER"></a>

将字符串转换为大写。UPPER 支持 UTF-8 多字节字符，并且每个字符最多可以有 4 个字节。

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

```
UPPER(string)
```

## 参数
<a name="r_UPPER-arguments"></a>

 *string*   
输入参数是 `VARCHAR` 字符串（或任何其他可隐式转换为 `VARCHAR` 的数据类型，如 `CHAR`）。

## 返回类型
<a name="r_UPPER-return-type"></a>

UPPER 函数返回与输入字符串具有相同数据类型的字符串。例如，如果输入是 `VARCHAR` 字符串，该函数将返回 `VARCHAR` 字符串。

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

以下示例使用 TICKIT 示例数据库的 CATEGORY 表中的数据。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

要将 CATNAME 字段转换为大写，请使用以下内容。

```
SELECT catname, UPPER(catname) 
FROM category 
ORDER BY 1,2;

+-----------+-----------+
|  catname  |   upper   |
+-----------+-----------+
| Classical | CLASSICAL |
| Jazz      | JAZZ      |
| MLB       | MLB       |
| MLS       | MLS       |
| Musicals  | MUSICALS  |
| NBA       | NBA       |
| NFL       | NFL       |
| NHL       | NHL       |
| Opera     | OPERA     |
| Plays     | PLAYS     |
| Pop       | POP       |
+-----------+-----------+
```

# SUPER 类型信息函数
<a name="c_Type_Info_Functions"></a>

接着，您可以找到 Amazon Redshift 支持的 SQL 的类型信息函数的描述，以从 `SUPER` 数据类型的输入中派生动态信息。

**Topics**
+ [DECIMAL\$1PRECISION 函数](r_decimal_precision.md)
+ [DECIMAL\$1SCALE 函数](r_decimal_scale.md)
+ [IS\$1ARRAY 函数](r_is_array.md)
+ [IS\$1BIGINT 函数](r_is_bigint.md)
+ [IS\$1BOOLEAN 函数](r_is_boolean.md)
+ [IS\$1CHAR 函数](r_is_char.md)
+ [IS\$1DECIMAL 函数](r_is_decimal.md)
+ [IS\$1FLOAT 函数](r_is_float.md)
+ [IS\$1INTEGER 函数](r_is_integer.md)
+ [IS\$1OBJECT 函数](r_is_object.md)
+ [IS\$1SCALAR 函数](r_is_scalar.md)
+ [IS\$1SMALLINT 函数](r_is_smallint.md)
+ [IS\$1VARCHAR 函数](r_is_varchar.md)
+ [JSON\$1SIZE 函数](r_json_size.md)
+ [JSON\$1TYPEOF 函数](r_json_typeof.md)
+ [SIZE](r_SIZE.md)

# DECIMAL\$1PRECISION 函数
<a name="r_decimal_precision"></a>

检查要存储的最大小数位数总数的精度。此数字包括小数点的左侧和右侧数字。精度范围为 1 到 38，默认值为 38。

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

```
DECIMAL_PRECISION(super_expression)
```

## 参数
<a name="r_decimal_precision-arguments"></a>

*super\$1expression*  
`SUPER` 表达式或列。

## 返回类型
<a name="r_decimal_precision-returns"></a>

`INTEGER`

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

要将 DECIMAL\$1PRECISION 函数应用于表 t，请使用以下示例。

```
CREATE TABLE t(s SUPER);

INSERT INTO t VALUES (3.14159);

SELECT DECIMAL_PRECISION(s) FROM t;

+-------------------+
| decimal_precision |
+-------------------+
|                 6 |
+-------------------+
```

# DECIMAL\$1SCALE 函数
<a name="r_decimal_scale"></a>

检查要存储在小数点右侧的小数位数。小数位数范围从 0 到精度点，默认值为 0。

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

```
DECIMAL_SCALE(super_expression)
```

## 参数
<a name="r_decimal_scale-arguments"></a>

*super\$1expression*  
`SUPER` 表达式或列。

## 返回类型
<a name="r_decimal_scale-returns"></a>

`INTEGER`

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

要将 DECIMAL\$1SCALE 函数应用于表 t，请使用以下示例。

```
CREATE TABLE t(s SUPER);

INSERT INTO t VALUES (3.14159);

SELECT DECIMAL_SCALE(s) FROM t;

+---------------+
| decimal_scale |
+---------------+
|             5 |
+---------------+
```

# IS\$1ARRAY 函数
<a name="r_is_array"></a>

检查变量是否为数组。如果变量是数组，则函数返回 `true`。该函数还包括空数组。否则，对于所有其他值，包括 null，函数返回 `false`。

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

```
IS_ARRAY(super_expression)
```

## 参数
<a name="r_is_array-arguments"></a>

*super\$1expression*  
`SUPER` 表达式或列。

## 返回类型
<a name="r_is_array-returns"></a>

`BOOLEAN`

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

要使用 IS\$1ARRAY 函数检查 `[1,2]` 是否为数组，请使用以下示例。

```
SELECT IS_ARRAY(JSON_PARSE('[1,2]'));

+----------+
| is_array |
+----------+
| true     |
+----------+
```

# IS\$1BIGINT 函数
<a name="r_is_bigint"></a>

检查某个值是否为 `BIGINT`。对于 64 位范围内的小数位数 0 的数量，IS\$1BIGINT 函数将返回 `true`。否则，对于所有其他值，包括 null 和浮点数，该函数将返回 `false`。

IS\$1BIGINT 函数是 IS\$1INTEGER 的超集。

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

```
IS_BIGINT(super_expression)
```

## 参数
<a name="r_is_bigint-arguments"></a>

*super\$1expression*  
`SUPER` 表达式或列。

## 返回类型
<a name="r_is_bigint-returns"></a>

`BOOLEAN`

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

要使用 IS\$1BIGINT 函数检查 `5` 是否为 `BIGINT`，请使用以下示例。

```
CREATE TABLE t(s SUPER);

INSERT INTO t VALUES (5);

SELECT s, IS_BIGINT(s) FROM t;

+---+-----------+
| s | is_bigint |
+---+-----------+
| 5 | true      |
+---+-----------+
```

# IS\$1BOOLEAN 函数
<a name="r_is_boolean"></a>

检查某个值是否为 `BOOLEAN`。对于常量 JSON 布尔值，IS\$1BOOLEAN 函数返回 `true`。对于任何其他值，包括 null，该函数返回 `false`。

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

```
IS_BOOLEAN(super_expression)
```

## 参数
<a name="r_is_boolean-arguments"></a>

*super\$1expression*  
`SUPER` 表达式或列。

## 返回类型
<a name="r_is_boolean-returns"></a>

`BOOLEAN`

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

要使用 IS\$1BOOLEAN 函数检查 `TRUE` 是否为 `BOOLEAN`，请使用以下示例。

```
CREATE TABLE t(s SUPER);

INSERT INTO t VALUES (TRUE);

SELECT s, IS_BOOLEAN(s) FROM t;

+------+------------+
|  s   | is_boolean |
+------+------------+
| true | true       |
+------+------------+
```

# IS\$1CHAR 函数
<a name="r_is_char"></a>

检查某个值是否为 `CHAR`。对于仅包含 ASCII 字符的字符串，IS\$1CHAR 函数返回 `true`，因为 CHAR 类型只能存储 ASCII 格式的字符。对于任何其他值，该函数返回 `false`。

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

```
IS_CHAR(super_expression)
```

## 参数
<a name="r_is_char-arguments"></a>

*super\$1expression*  
`SUPER` 表达式或列。

## 返回类型
<a name="r_is_char-returns"></a>

`BOOLEAN`

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

要使用 IS\$1CHAR 函数检查 `t` 是否为 `CHAR`，请使用以下示例。

```
CREATE TABLE t(s SUPER);

INSERT INTO t VALUES ('t');

SELECT s, IS_CHAR(s) FROM t;

+-----+---------+
|  s  | is_char |
+-----+---------+
| "t" | true    |
+-----+---------+
```

# IS\$1DECIMAL 函数
<a name="r_is_decimal"></a>

检查某个值是否为 `DECIMAL`。对于非浮点的数值，IS\$1DECIMAL 函数返回 `true`。对于任何其他值，包括 null，该函数返回 `false`。

IS\$1DECIMAL 函数是 IS\$1BIGINT 的超集。

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

```
IS_DECIMAL(super_expression)
```

## 参数
<a name="r_is_decimal-arguments"></a>

*super\$1expression*  
`SUPER` 表达式或列。

## 返回类型
<a name="r_is_decimal-returns"></a>

`BOOLEAN`

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

要使用 IS\$1DECIMAL 函数检查 `1.22` 是否为 `DECIMAL`，请使用以下示例。

```
CREATE TABLE t(s SUPER);

INSERT INTO t VALUES (1.22);

SELECT s, IS_DECIMAL(s) FROM t;

+------+------------+
|  s   | is_decimal |
+------+------------+
| 1.22 | true       |
+------+------------+
```

# IS\$1FLOAT 函数
<a name="r_is_float"></a>

检查值是否为浮点数。对于浮点数（`FLOAT4` 和 `FLOAT8`），IS\$1FLOAT 函数返回 `true`。对于任何其他值，该函数返回 `false`。

IS\$1DECIMAL 集和 IS\$1FLOAT 集是不相交的。

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

```
IS_FLOAT(super_expression)
```

## 参数
<a name="r_is_float-arguments"></a>

*super\$1expression*  
`SUPER` 表达式或列。

## 返回类型
<a name="r_is_float-returns"></a>

`BOOLEAN`

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

要使用 IS\$1FLOAT 函数检查 `2.22::FLOAT` 是否为 `FLOAT`，请使用以下示例。

```
CREATE TABLE t(s SUPER);

INSERT INTO t VALUES(2.22::FLOAT);

SELECT s, IS_FLOAT(s) FROM t;

+---------+----------+
|    s    | is_float |
+---------+----------+
| 2.22e+0 | true     |
+---------+----------+
```

# IS\$1INTEGER 函数
<a name="r_is_integer"></a>

对于 32 位范围内的小数位数 0 的数量，返回 `true`；对于其他任何值（包括 null 和浮点数），则返回 `false`。

IS\$1INTEGER 函数是 IS\$1SMALLINT 函数的超集。

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

```
IS_INTEGER(super_expression)
```

## 参数
<a name="r_is_integer-arguments"></a>

*super\$1expression*  
`SUPER` 表达式或列。

## 返回类型
<a name="r_is_integer-returns"></a>

`BOOLEAN`

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

要使用 IS\$1INTEGER 函数检查 `5` 是否为 `INTEGER`，请使用以下示例。

```
CREATE TABLE t(s SUPER);

INSERT INTO t VALUES (5);

SELECT s, IS_INTEGER(s) FROM t;

+---+------------+
| s | is_integer |
+---+------------+
| 5 | true       |
+---+------------+
```

# IS\$1OBJECT 函数
<a name="r_is_object"></a>

检查变量是否为对象。对于包括空对象在内的对象，IS\$1OBJECT 函数返回 `true`。对于任何其他值，包括 null，该函数返回 `false`。

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

```
IS_OBJECT(super_expression)
```

## 参数
<a name="r_is_object-arguments"></a>

*super\$1expression*  
`SUPER` 表达式或列。

## 返回类型
<a name="r_is_object-returns"></a>

`BOOLEAN`

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

要使用 IS\$1OBJECT 函数检查 `{"name": "Joe"}` 是否为对象，请使用以下示例。

```
CREATE TABLE t(s super);

INSERT INTO t VALUES (JSON_PARSE('{"name": "Joe"}'));

SELECT s, IS_OBJECT(s) FROM t;

+----------------+-----------+
|       s        | is_object |
+----------------+-----------+
| {"name":"Joe"} | true      |
+----------------+-----------+
```

# IS\$1SCALAR 函数
<a name="r_is_scalar"></a>

检查变量是否为标量。对于非数组或对象的任何值，IS\$1SCALAR 函数返回 `true`。对于任何其他值，包括 null，该函数返回 `false`。

IS\$1ARRAY、IS\$1OBJECT 和 IS\$1SCALAR 的集合覆盖除 null 之外的所有值。

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

```
IS_SCALAR(super_expression)
```

## 参数
<a name="r_is_scalar-arguments"></a>

*super\$1expression*  
`SUPER` 表达式或列。

## 返回类型
<a name="r_is_scalar-returns"></a>

`BOOLEAN`

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

要使用 IS\$1SCALAR 函数检查 `{"name": "Joe"}` 是否为标量，请使用以下示例。

```
CREATE TABLE t(s SUPER);

INSERT INTO t VALUES (JSON_PARSE('{"name": "Joe"}'));

SELECT s, IS_SCALAR(s.name) FROM t;

+----------------+-----------+
|       s        | is_scalar |
+----------------+-----------+
| {"name":"Joe"} | true      |
+----------------+-----------+
```

# IS\$1SMALLINT 函数
<a name="r_is_smallint"></a>

检查变量是否为 `SMALLINT`。对于 16 位范围内的小数位数 0 的数量，IS\$1SMALLINT 函数返回 `true`。对于任何其他值，包括 null 和浮点数，该函数返回 `false`。

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

```
IS_SMALLINT(super_expression)
```

## 参数
<a name="r_is_smallint-arguments"></a>

*super\$1expression*  
`SUPER` 表达式或列。

## Return
<a name="r_is_smallint-returns"></a>

`BOOLEAN`

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

要使用 IS\$1SMALLINT 函数检查 `5` 是否为 `SMALLINT`，请使用以下示例。

```
CREATE TABLE t(s SUPER);

INSERT INTO t VALUES (5);

SELECT s, IS_SMALLINT(s) FROM t;

+---+-------------+
| s | is_smallint |
+---+-------------+
| 5 | true        |
+---+-------------+
```

# IS\$1VARCHAR 函数
<a name="r_is_varchar"></a>

检查变量是否为 `VARCHAR`。对于所有字符串，IS\$1VARCHAR 函数返回 `true`。对于任何其他值，该函数返回 `false`。

IS\$1VARCHAR 函数是 IS\$1CHAR 函数的超集。

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

```
IS_VARCHAR(super_expression)
```

## 参数
<a name="r_is_varchar-arguments"></a>

*super\$1expression*  
`SUPER` 表达式或列。

## 返回类型
<a name="r_is_varchar-returns"></a>

`BOOLEAN`

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

要使用 IS\$1VARCHAR 函数检查 `abc` 是否为 `VARCHAR`，请使用以下示例。

```
CREATE TABLE t(s SUPER);

INSERT INTO t VALUES ('abc');

SELECT s, IS_VARCHAR(s) FROM t;

+-------+------------+
|   s   | is_varchar |
+-------+------------+
| "abc" | true       |
+-------+------------+
```

# JSON\$1SIZE 函数
<a name="r_json_size"></a>

当序列化为字符串时，JSON\$1SIZE 函数返回给定 `SUPER` 表达式中的字节数。

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

```
JSON_SIZE(super_expression)
```

## 参数
<a name="r_json_size-arguments"></a>

*super\$1expression*  
`SUPER` 常量或表达式。

## 返回类型
<a name="r_json_size-returns"></a>

`INTEGER`  
JSON\$1SIZE 函数返回一个 `INTEGER`，表示输入字符串中的字节数。此值不同于字符数。例如，UTF-8 字符 ⬤（黑点）的大小为 3 字节，即使它是 1 个字符也是如此。

## 使用说明
<a name="r_json_size-usage_notes"></a>

JSON\$1SIZE(x) 在功能上与 OCTET\$1LENGTH(JSON\$1SERIALIZE) 相同。但请注意，如果提供的 `SUPER` 表达式在序列化时超过系统的 `VARCHAR` 限制，JSON\$1SERIALIZE 会返回错误。JSON\$1SIZE 没有这个限制。

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

要返回序列化为字符串的 `SUPER` 值的长度，请使用以下示例。

```
SELECT JSON_SIZE(JSON_PARSE('[10001,10002,"⬤"]'));

+-----------+
| json_size |
+-----------+
|        19 |
+-----------+
```

请注意，提供的 `SUPER` 表达式长度为 17 个字符，但 ⬤ 为 3 字节字符，因此 JSON\$1SIZE 返回 `19`。

# JSON\$1TYPEOF 函数
<a name="r_json_typeof"></a>

根据 `SUPER` 值的动态类型，JSON\$1TYPEOF 标量函数返回具有布尔值、数值、字符串、对象、数组或 null 的 `VARCHAR`。

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

```
JSON_TYPEOF(super_expression)
```

## 参数
<a name="r_json_typeof-arguments"></a>

*super\$1expression*  
`SUPER` 表达式或列。

## 返回类型
<a name="r_json_typeof-returns"></a>

`VARCHAR`

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

要使用 JSON\$1TYPEOF 函数检查数组 `[1,2]` 的 JSON 类型，请使用以下示例。

```
SELECT JSON_TYPEOF(ARRAY(1,2));

+-------------+
| json_typeof |
+-------------+
| array       |
+-------------+
```

要使用 JSON\$1TYPEOF 函数检查对象 `{"name":"Joe"}` 的 JSON 类型，请使用以下示例。

```
SELECT JSON_TYPEOF(JSON_PARSE('{"name":"Joe"}'));

+-------------+
| json_typeof |
+-------------+
| object      |
+-------------+
```

# SIZE
<a name="r_SIZE"></a>

 以 `INTEGER` 形式返回 `SUPER` 类型常量或表达式的二进制内存大小。

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

```
SIZE(super_expression)
```

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

*super\$1expression*  
 `SUPER` 类型的常量或表达式。

## 返回类型
<a name="r_SIZE-returns"></a>

`INTEGER`

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

 要使用 SIZE 获取多个 `SUPER` 类型表达式的内存大小，请使用以下示例。

```
CREATE TABLE test_super_size(a SUPER);
            
INSERT INTO test_super_size 
VALUES
  (null),
  (TRUE),
  (JSON_PARSE('[0,1,2,3]')),
  (JSON_PARSE('{"a":0,"b":1,"c":2,"d":3}'))
;

SELECT a, SIZE(a) 
FROM test_super_size 
ORDER BY 2, 1;

+---------------------------+------+
|             a             | size |
+---------------------------+------+
| true                      |    4 |
| NULL                      |    4 |
| [0,1,2,3]                 |   23 |
| {"a":0,"b":1,"c":2,"d":3} |   52 |
+---------------------------+------+
```

# VARBYTE 函数和运算符
<a name="varbyte-functions"></a>

支持 VARBYTE 数据类型的 Amazon Redshift 函数和运算符包括：
+ [VARBYTE 运算符](r_VARBYTE_OPERATORS.md)
+ [FROM\$1HEX](r_FROM_HEX.md)
+ [FROM\$1VARBYTE](r_FROM_VARBYTE.md)
+ [GETBIT](r_GETBIT.md)
+ [TO\$1HEX](r_TO_HEX.md)
+ [TO\$1VARBYTE](r_TO_VARBYTE.md)
+ [CONCAT](r_CONCAT.md)
+ [LEN](r_LEN.md)
+ [LENGTH 函数](r_LENGTH.md)
+ [OCTET\$1LENGTH](r_OCTET_LENGTH.md)
+ [SUBSTRING 函数](r_SUBSTRING.md)

# VARBYTE 运算符
<a name="r_VARBYTE_OPERATORS"></a>

 下表列出了 VARBYTE 运算符。运算符使用数据类型为 VARBYTE 的二进制值。如果一个或两个输入为 null，则结果也为 null。

## 支持的运算符
<a name="r_VARBYTE_OPERATORS-supported-operators"></a>

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_VARBYTE_OPERATORS.html)

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

在以下示例中，`'a'::VARBYTE` 的值 是 `61`，`'b'::VARBYTE` 的值是 `62`。`::` 将字符串强制转换为 `VARBYTE` 数据类型。有关强制转换数据类型的更多信息，请参阅[CAST](r_CAST_function.md)。

要使用 `<` 运算符比较 `'a'` 是否小于 `'b'`，请使用以下示例。

```
SELECT 'a'::VARBYTE < 'b'::VARBYTE AS less_than;
               
+-----------+
| less_than |
+-----------+
| true      |
+-----------+
```

要使用 `=` 运算符比较 `'a'` 是否等于 `'b'`，请使用以下示例。

```
SELECT 'a'::VARBYTE = 'b'::VARBYTE AS equal;
               
+-------+
| equal |
+-------+
| false |
+-------+
```

要使用 `||` 运算符连接两个二进制值，请使用以下示例。

```
SELECT 'a'::VARBYTE || 'b'::VARBYTE AS concat;
               
+--------+
| concat |
+--------+
|   6162 |
+--------+
```

要使用 `+` 运算符连接两个二进制值，请使用以下示例。

```
SELECT 'a'::VARBYTE + 'b'::VARBYTE AS concat;
               
+--------+
| concat |
+--------+
|   6162 |
+--------+
```

要使用 FROM\$1VARBYTE 函数否定输入二进制值的每个位，请使用以下示例。字符串 `'a'` 计算结果为 `01100001`。有关更多信息，请参阅 [FROM\$1VARBYTE](r_FROM_VARBYTE.md)。

```
SELECT FROM_VARBYTE(~'a'::VARBYTE, 'binary');
               
+--------------+
| from_varbyte |
+--------------+
|     10011110 |
+--------------+
```

要在两个输入二进制值上应用 `&` 运算符，请使用以下示例。字符串 `'a'` 计算结果为 `01100001`，而 `'b'` 计算结果为 `01100010`。

```
SELECT FROM_VARBYTE('a'::VARBYTE & 'b'::VARBYTE, 'binary');
               
+--------------+
| from_varbyte |
+--------------+
|     01100000 |
+--------------+
```

# FROM\$1HEX 函数
<a name="r_FROM_HEX"></a>

FROM\$1HEX 将十六进制转换为二进制值。

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

```
FROM_HEX(hex_string)
```

## 参数
<a name="r_FROM_HEX-arguments"></a>

 *hex\$1string*   
要转换的数据类型为 `VARCHAR` 或 `TEXT` 的十六进制字符串。格式必须是文本值。

## 返回类型
<a name="r_FROM_HEX-return-type"></a>

`VARBYTE`

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

要将 `'6162'` 的十六进制表示形式转换为二进制值，请使用以下示例。结果会自动显示为二进制值的十六进制表示形式。

```
SELECT FROM_HEX('6162');
               
+----------+
| from_hex |
+----------+
|     6162 |
+----------+
```

# FROM\$1VARBYTE 函数
<a name="r_FROM_VARBYTE"></a>

FROM\$1VARBYTE 将二进制值转换为指定格式的字符串。

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

```
FROM_VARBYTE(binary_value, format)
```

## 参数
<a name="r_FROM_VARBYTE-arguments"></a>

 *binary\$1value*   
数据类型为 `VARBYTE` 的二进制值。

 *格式的日期和时间*。  
返回的字符串格式。不区分大小写的有效值为 `hex`、`binary`、`utf8`（还包括 `utf-8` 和 `utf_8`）和 `base64`。

## 返回类型
<a name="r_FROM_VARBYTE-return-type"></a>

`VARCHAR`

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

要将二进制值 `'ab'` 转换为十六进制，请使用以下示例。

```
SELECT FROM_VARBYTE('ab', 'hex');
               
+--------------+
| from_varbyte |
+--------------+
|         6162 |
+--------------+
```

要返回 `'4d'` 的二进制表示形式，请使用以下示例。`'4d'` 的二进制表示形式是字符串 `01001101`。

```
SELECT FROM_VARBYTE(FROM_HEX('4d'), 'binary');
               
+--------------+
| from_varbyte |
+--------------+
|     01001101 |
+--------------+
```

# GETBIT 函数
<a name="r_GETBIT"></a>

GETBIT 返回指定索引处二进制值的位值。

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

```
GETBIT(binary_value, index)
```

## 参数
<a name="r_GETBIT-arguments"></a>

 *binary\$1value*   
数据类型为 `VARBYTE` 的二进制值。

 *index*   
返回的二进制值中的位的索引号。二进制值是一个从 0 开始的位数组，它从最右边的位（最低有效位）索引到最左边的位（最高有效位）。

## 返回类型
<a name="r_GETBIT-return-type"></a>

`INTEGER`

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

要返回二进制值 `from_hex('4d')` 在 `2` 索引处的位，请使用以下示例。`'4d'` 的二进制表示形式是 `01001101`。

```
SELECT GETBIT(FROM_HEX('4d'), 2);
               
+--------+
| getbit |
+--------+
|      1 |
+--------+
```

要返回由 `from_hex('4d')` 返回的二进制值在八个索引位置的位，请使用以下示例。`'4d'` 的二进制表示形式是 `01001101`。

```
SELECT GETBIT(FROM_HEX('4d'), 7), GETBIT(FROM_HEX('4d'), 6),
  GETBIT(FROM_HEX('4d'), 5), GETBIT(FROM_HEX('4d'), 4),
  GETBIT(FROM_HEX('4d'), 3), GETBIT(FROM_HEX('4d'), 2),
  GETBIT(FROM_HEX('4d'), 1), GETBIT(FROM_HEX('4d'), 0);
               
+--------+--------+--------+--------+--------+--------+--------+--------+
| getbit | getbit | getbit | getbit | getbit | getbit | getbit | getbit |
+--------+--------+--------+--------+--------+--------+--------+--------+
|      0 |      1 |      0 |      0 |      1 |      1 |      0 |      1 |
+--------+--------+--------+--------+--------+--------+--------+--------+
```

# TO\$1HEX 函数
<a name="r_TO_HEX"></a>

TO\$1HEX 将数字或二进制值转换为十六进制表示形式。

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

```
TO_HEX(value)
```

## 参数
<a name="r_TO_HEX-arguments"></a>

 *值*   
要转换的数值或二进制值（`VARBYTE`）。

## 返回类型
<a name="r_TO_HEX-return-type"></a>

`VARCHAR`

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

要将一个数值转换为其十六进制表示形式，请使用以下示例。

```
SELECT TO_HEX(2147676847);
               
+----------+
|  to_hex  |
+----------+
| 8002f2af |
+----------+
```

要将 `'abc'` 的 `VARBYTE` 表示形式转换为十六进制数值，请使用以下示例。

```
SELECT TO_HEX('abc'::VARBYTE);
               
+--------+
| to_hex |
+--------+
| 616263 |
+--------+
```

要创建一个表，将 `'abc'` 的 `VARBYTE` 表示形式插入到一个十六进制数值，然后选择具有该值的列，请使用以下示例。

```
CREATE TABLE t (vc VARCHAR);
INSERT INTO t SELECT TO_HEX('abc'::VARBYTE);
SELECT vc FROM t;
 
+--------+
|   vc   |
+--------+
| 616263 |
+--------+
```

要显示将 `VARBYTE` 值强制转换为 `VARCHAR` 时，格式为 UTF-8，请使用以下示例。

```
CREATE TABLE t (vc VARCHAR);
INSERT INTO t SELECT 'abc'::VARBYTE::VARCHAR;

SELECT vc FROM t;

+-----+
| vc  |
+-----+
| abc |
+-----+
```

# TO\$1VARBYTE 函数
<a name="r_TO_VARBYTE"></a>

TO\$1VARBYTE 将指定格式的字符串转换为二进制值。

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

```
TO_VARBYTE(string, format)
```

## 参数
<a name="r_TO_VARBYTE-arguments"></a>

 *string*   
`CHAR` 或 `VARCHAR` 字符串。

 *格式的日期和时间*。  
输入字符串的格式。不区分大小写的有效值为 `hex`、`binary`、`utf8`（还包括 `utf-8` 和 `utf_8`）和 `base64`。

## 返回类型
<a name="r_TO_VARBYTE-return-type"></a>

`VARBYTE`

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

要将十六进制 `6162` 转换为二进制值，请使用以下示例。结果会自动显示为二进制值的十六进制表示形式。

```
SELECT TO_VARBYTE('6162', 'hex');
               
+------------+
| to_varbyte |
+------------+
|       6162 |
+------------+
```

要返回 `4d` 的二进制表示形式，请使用以下示例。“4d”的二进制表示形式是字符串 `01001101`。

```
SELECT TO_VARBYTE('01001101', 'binary');
               
+------------+
| to_varbyte |
+------------+
|         4d |
+------------+
```

要将 UTF-8 格式的字符串 `'a'` 转换为二进制值，请使用以下示例。结果会自动显示为二进制值的十六进制表示形式。

```
SELECT TO_VARBYTE('a', 'utf8');
               
+------------+
| to_varbyte |
+------------+
|         61 |
+------------+
```

要将十六进制的字符串 `'4'` 转换为二进制值，请使用以下示例。如果十六进制字符串长度为奇数，则需添加一个 `0`，形成一个有效的十六进制数字。

```
SELECT TO_VARBYTE('4', 'hex');
               
+------------+
| to_varbyte |
+------------+
|         04 |
+------------+
```

# 窗口函数
<a name="c_Window_functions"></a>

通过使用窗口函数，您可以更高效地创建分析业务查询。窗口函数运行于分区或结果集的“窗口”上，并为该窗口中的每个行返回一个值。相比之下，非窗口函数执行与结果集中的每个行相关的计算。与聚合结果行的分组函数不同，窗口函数在表的表达式中的保留所有行。

 使用该窗口中的行集中的值计算返回的值。对于表中的每一行，窗口定义一组用于计算其他属性的行。窗口使用窗口规范（OVER 子句）进行定义并基于以下三个主要概念：
+  *窗口分区*，构成了行组（PARTITION 子句） 
+  *窗口排序*，定义了每个分区中行的顺序或序列（ORDER BY 子句） 
+  *窗口框架*，相对于每个行进行定义以进一步限制行集（ROWS 规范） 

窗口函数是在查询中执行的最后一组操作（最后的 ORDER BY 子句除外）。所有联接和所有 WHERE、GROUP BY 和 HAVING 子句均在处理窗口函数前完成。因此，窗口函数只能显示在选择列表或 ORDER BY 子句中。您可以在一个具有不同框架子句的查询中使用多个窗口函数。您还可以在其他标量表达式（如 CASE）中使用窗口函数。

窗口函数不能嵌套。例如，聚合函数 [SUM](r_SUM.md) 可以出现在窗口函数 [SUM](r_WF_SUM.md) 内，但一个窗口函数 SUM 不能出现在另一个窗口函数 SUM 内。由于一个窗口函数嵌套在另一个窗口函数中，因此不支持以下操作。

```
SELECT SUM(SUM(selectcol) OVER (PARTITION BY ordercol)) OVER (Partition by ordercol) FROM t;
```

## 窗口函数语法摘要
<a name="r_Window_function_synopsis"></a>

窗口函数遵循标准语法，如下所示。

```
function (expression) OVER (
[ PARTITION BY expr_list ]
[ ORDER BY order_list [ frame_clause ] ] )
```

 其中，*function* 是本部分介绍的函数之一。

*expr\$1list* 如下所示。

```
expression | column_name [, expr_list ]
```

 *order\$1list* 如下所示。

```
expression | column_name [ ASC | DESC ] 
[ NULLS FIRST | NULLS LAST ]
[, order_list ]
```

 *frame\$1clause* 如下所示。

```
ROWS
{ UNBOUNDED PRECEDING | unsigned_value PRECEDING | CURRENT ROW } |

{ BETWEEN
{ UNBOUNDED PRECEDING | unsigned_value { PRECEDING | FOLLOWING } | CURRENT ROW}
AND
{ UNBOUNDED FOLLOWING | unsigned_value { PRECEDING | FOLLOWING } | CURRENT ROW }}
```

### 参数
<a name="r_Window_function_synopsis-arguments"></a>

 *函数*   
窗口函数。有关详细信息，请参阅各个函数描述。

OVER   
定义窗口规范的子句。OVER 子句是窗口函数必需的，并可区分窗口函数与其他 SQL 函数。

PARTITION BY *expr\$1list*   
（可选）PARTITION BY 子句将结果集细分为分区，与 GROUP BY 子句很类似。如果存在分区子句，则为每个分区中的行计算该函数。如果未指定任何分区子句，则一个分区包含整个表，并为整个表计算该函数。  
排名函数 DENSE\$1RANK、NTILE、RANK 和 ROW\$1NUMBER 需要全局比较结果集中的所有行。使用 PARTITION BY 子句时，查询优化程序可通过根据分区跨多个切片分布工作负载来并行运行每个聚合。如果不存在 PARTITION BY 子句，则必须在一个切片上按顺序运行聚合步骤，这可能对性能产生显著的负面影响，特别是对于大型集群。  
Amazon Redshift 不支持 PARTITION BY 子句中的字符串文本。

ORDER BY *order\$1list*   
（可选）窗口函数将应用于每个分区中根据 ORDER BY 中的顺序规范排序的行。此 ORDER BY 子句与 *frame\$1clause* 中的 ORDER BY 子句不同且完全不相关。ORDER BY 子句可在没有 PARTITION BY 子句的情况下使用。  
对于排名函数，ORDER BY 子句确定排名值的度量。对于聚合函数，分区的行必须在为每个框架计算聚合函数之前进行排序。有关窗口函数的更多信息，请参阅 [窗口函数](#c_Window_functions)。  
顺序列表中需要列标识符或计算结果为列标识符的表达式。常数和常数表达式都不可用作列名称的替代。  
NULLS 值将被视为其自己的组，并根据 NULLS FIRST 或 NULLS LAST 选项进行排序和排名。默认情况下，按 ASC 顺序最后对 NULL 值进行排序和排名，按 DESC 顺序首先对 NULL 值进行排序和排名。  
Amazon Redshift 不支持 ORDER BY 子句中的字符串文本。  
 如果省略 ORDER BY 子句，则行的顺序是不确定的。  
在任何并行系统（如 Amazon Redshift）中，如果 ORDER BY 子句未生成数据的唯一排序和总排序，则行的顺序是不确定的。也就是说，如果 ORDER BY 表达式生成重复的值（部分排序），则这些行的返回顺序可能会因 Amazon Redshift 的运行而异。反过来，窗口函数可能返回意外的或不一致的结果。有关更多信息，请参阅 [窗口函数的唯一数据排序](#r_Examples_order_by_WF)。

 *column\$1name*   
执行分区或排序操作所依据的列的名称。

ASC \$1 DESC   
一个定义表达式的排序顺序的选项，如下所示：  
+ ASC：升序（例如，按数值的从低到高的顺序和字符串的从 A 到 Z 的顺序）。如果未指定选项，则默认情况下将按升序对数据进行排序。
+ DESC：降序（按数值的从高到低的顺序和字符串的从 Z 到 A 的顺序）。

NULLS FIRST \$1 NULLS LAST  
指定是应首先对 NULL 值进行排序（非 null 值之前）还是最后对 NULL 值进行排序（非 null 值之后）的选项。默认情况下，按 ASC 顺序最后对 NULLS 进行排序和排名，按 DESC 顺序首先对 NULLS 进行排序和排名。

 *frame\$1clause*   
对于聚合函数，框架子句在使用 ORDER BY 时进一步优化函数窗口中的行集。它使您可以包含或排除已排序结果中的行集。框架子句包括 ROWS 关键字和关联的说明符。  
frame 子句不适用于排名函数。同时，在聚合函数的 OVER 子句中未使用 ORDER BY 子句时不需要框架子句。如果 ORDER BY 子句用于聚合函数，则需要显式框架子句。  
未指定 ORDER BY 子句时，隐式框架是无界的：等同于 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。

ROWS  
此子句通过从当前行中指定物理偏移来定义窗口框架。  
此子句指定当前行中的值将并入的当前窗口或分区中的行。它使用指定行位置的参数，行位置可位于当前行之前或之后。所有窗口框架的参考点为当前行。当窗口框架向前滑向分区中时，每个行会依次成为当前行。  
框架可以是一组超过并包括当前行的行。  

```
{UNBOUNDED PRECEDING | offset PRECEDING | CURRENT ROW}
```
或者可以是两个边界之间的一组行。  

```
BETWEEN
{ UNBOUNDED PRECEDING | offset { PRECEDING | FOLLOWING } | CURRENT ROW }
AND
{ UNBOUNDED FOLLOWING | offset { PRECEDING | FOLLOWING } | CURRENT ROW }
```
UNBOUNDED PRECEDING 指示窗口从分区的第一行开始；*offset* PRECEDING 指示窗口开始于等同于当前行之前的偏移值的行数。UNBOUNDED PRECEDING 是默认值。  
CURRENT ROW 指示窗口在当前行开始或结束。  
UNBOUNDED FOLLOWING 指示窗口在分区的最后一行结束；*offset* FOLLOWING 指示窗口结束于等同于当前行之后的偏移值的行数。  
*offset* 标识当前行之前或之后的实际行数。在这种情况下，*offset* 必须为计算结果为正数值的常数。例如，5 FOLLOWING 将在当前行之后的第 5 行结束框架。  
其中，未指定 BETWEEN，框架受当前行隐式限制。例如，`ROWS 5 PRECEDING` 等于 `ROWS BETWEEN 5 PRECEDING AND CURRENT ROW`。同时，`ROWS UNBOUNDED FOLLOWING` 等于 `ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING`。  
您无法指定起始边界大于结束边界的框架。例如，您无法指定以下任一框架。  

```
between 5 following and 5 preceding
between current row and 2 preceding
between 3 following and current row
```

## 窗口函数的唯一数据排序
<a name="r_Examples_order_by_WF"></a>

如果窗口函数的 ORDER BY 子句不生成数据的唯一排序和总排序，则行的顺序是不确定的。如果 ORDER BY 表达式生成重复的值（部分排序），则这些行的返回顺序可能会在多次运行中有所不同。在这种情况下，窗口函数还可能返回意外的或不一致的结果。

例如，以下查询在多次运行中返回了不同的结果。出现这些不同的结果是因为 `order by dateid` 未生成 SUM 窗口函数的数据的唯一排序。

```
select dateid, pricepaid,
sum(pricepaid) over(order by dateid rows unbounded preceding) as sumpaid
from sales
group by dateid, pricepaid;

dateid | pricepaid |   sumpaid
--------+-----------+-------------
1827 |   1730.00 |     1730.00
1827 |    708.00 |     2438.00
1827 |    234.00 |     2672.00
...

select dateid, pricepaid,
sum(pricepaid) over(order by dateid rows unbounded preceding) as sumpaid
from sales
group by dateid, pricepaid;

dateid | pricepaid |   sumpaid
--------+-----------+-------------
1827 |    234.00 |      234.00
1827 |    472.00 |      706.00
1827 |    347.00 |     1053.00
...
```

 在这种情况下，向该窗口函数添加另一个 ORDER BY 列可解决此问题。

```
select dateid, pricepaid,
sum(pricepaid) over(order by dateid, pricepaid rows unbounded preceding) as sumpaid
from sales
group by dateid, pricepaid;

dateid | pricepaid | sumpaid
--------+-----------+---------
1827 |    234.00 |  234.00
1827 |    337.00 |  571.00
1827 |    347.00 |  918.00
...
```

## 支持的函数
<a name="r_Window_function_supported"></a>

Amazon Redshift 支持以下两种类型的窗口函数：聚合和排名。

以下是支持的聚合函数：
+ [AVG 窗口函数](r_WF_AVG.md)
+ [COUNT 窗口函数](r_WF_COUNT.md)
+ [CUME\$1DIST 开窗函数](r_WF_CUME_DIST.md)
+ [DENSE\$1RANK 窗口函数](r_WF_DENSE_RANK.md)
+ [FIRST\$1VALUE 窗口函数](r_WF_first_value.md)
+ [LAG 窗口函数](r_WF_LAG.md) 
+ [LAST\$1VALUE 窗口函数](r_WF_last_value.md)
+ [LEAD 窗口函数](r_WF_LEAD.md) 
+ [LISTAGG 窗口函数](r_WF_LISTAGG.md) 
+ [MAX 窗口函数](r_WF_MAX.md) 
+ [MEDIAN 开窗函数](r_WF_MEDIAN.md) 
+ [MIN 窗口函数](r_WF_MIN.md) 
+ [NTH\$1VALUE 窗口函数](r_WF_NTH.md) 
+ [PERCENTILE\$1CONT 开窗函数](r_WF_PERCENTILE_CONT.md)
+ [PERCENTILE\$1DISC 开窗函数](r_WF_PERCENTILE_DISC.md)
+ [RATIO\$1TO\$1REPORT 开窗函数](r_WF_RATIO_TO_REPORT.md)
+ [STDDEV\$1SAMP 和 STDDEV\$1POP 窗口函数](r_WF_STDDEV.md)（STDDEV\$1SAMP 和 STDDEV 是同义词） 
+ [SUM 窗口函数](r_WF_SUM.md) 
+ [VAR\$1SAMP 和 VAR\$1POP 窗口函数](r_WF_VARIANCE.md)（VAR\$1SAMP 和 VARIANCE 是同义词）

以下是支持的排名函数：
+ [DENSE\$1RANK 窗口函数](r_WF_DENSE_RANK.md) 
+ [NTILE 窗口函数](r_WF_NTILE.md) 
+ [PERCENT\$1RANK 开窗函数](r_WF_PERCENT_RANK.md)
+ [RANK 窗口函数](r_WF_RANK.md) 
+ [ROW\$1NUMBER 窗口函数](r_WF_ROW_NUMBER.md)

## 窗口函数示例的示例表
<a name="r_Window_function_example"></a>

您可以通过每个函数描述找到特定的窗口函数示例。其中一些示例使用一个名为 WINSALES 的表，该表包含 11 个行，如下所示。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/c_Window_functions.html)

以下脚创建并填充示例 WINSALES 表。

```
CREATE TABLE winsales(
  salesid int,
  dateid date,
  sellerid int,
  buyerid char(10),
  qty int,
  qty_shipped int);

INSERT INTO winsales VALUES
  (30001, '8/2/2003', 3, 'b', 10, 10),
  (10001, '12/24/2003', 1, 'c', 10, 10),
  (10005, '12/24/2003', 1, 'a', 30, null),	
  (40001, '1/9/2004', 4, 'a', 40, null),	
  (10006, '1/18/2004', 1, 'c', 10, null),	
  (20001, '2/12/2004', 2, 'b', 20, 20),
  (40005, '2/12/2004', 4, 'a', 10, 10),
  (20002, '2/16/2004', 2, 'c', 20, 20),
  (30003, '4/18/2004', 3, 'b', 15, null),
  (30004, '4/18/2004', 3, 'b', 20, null),	
  (30007, '9/7/2004', 3, 'c', 30, null);
```

# AVG 窗口函数
<a name="r_WF_AVG"></a>

 AVG 窗口函数返回输入表达式值的平均值（算术平均值）。AVG 函数使用数值并忽略 NULL 值。

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

```
AVG ( [ALL ] expression ) OVER
(
[ PARTITION BY expr_list ]
[ ORDER BY order_list 
                        frame_clause ]
)
```

## 参数
<a name="r_WF_AVG-arguments"></a>

 *expression*   
对其执行函数的目标列或表达式。

ALL   
利用参数 ALL，该函数可保留表达式中的所有重复值以进行计数。ALL 是默认值。DISTINCT 不受支持。

OVER   
指定聚合函数的窗口子句。OVER 子句将窗口聚合函数与普通集合聚合函数区分开来。

PARTITION BY *expr\$1list*   
依据一个或多个表达式定义 AVG 函数的窗口。

ORDER BY *order\$1list*   
对每个分区中的行进行排序。如果未指定 PARTITION BY，则 ORDER BY 使用整个表。

 *frame\$1clause*   
如果 ORDER BY 子句用于聚合函数，则需要显式框架子句。框架子句优化函数窗口中的行集，包含或排除已排序结果中的行集。框架子句包括 ROWS 关键字和关联的说明符。请参阅 [窗口函数语法摘要](c_Window_functions.md#r_Window_function_synopsis)。

## 数据类型
<a name="c_Supported_data_types_wf_avg"></a>

AVG 函数支持的参数类型为 SMALLINT、INTEGER、BIGINT、NUMERIC、DECIMAL、REAL 和 DOUBLE PRECISION。

AVG 函数支持的返回类型为：
+ 适用于 SMALLINT 或 INTEGER 参数的 BIGINT
+ 适用于 BIGINT 参数的 NUMERIC
+ 适用于浮点参数的 DOUBLE PRECISION

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

以下示例按日期计算销量的移动平均数；按日期 ID 和销售 ID 对结果进行排序：

```
select salesid, dateid, sellerid, qty,
avg(qty) over
(order by dateid, salesid rows unbounded preceding) as avg
from winsales
order by 2,1;

salesid |   dateid   | sellerid | qty | avg
---------+------------+----------+-----+-----
30001 | 2003-08-02 |        3 |  10 |  10
10001 | 2003-12-24 |        1 |  10 |  10
10005 | 2003-12-24 |        1 |  30 |  16
40001 | 2004-01-09 |        4 |  40 |  22
10006 | 2004-01-18 |        1 |  10 |  20
20001 | 2004-02-12 |        2 |  20 |  20
40005 | 2004-02-12 |        4 |  10 |  18
20002 | 2004-02-16 |        2 |  20 |  18
30003 | 2004-04-18 |        3 |  15 |  18
30004 | 2004-04-18 |        3 |  20 |  18
30007 | 2004-09-07 |        3 |  30 |  19
(11 rows)
```

 有关 WINSALES 表的说明，请参阅[窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

# COUNT 窗口函数
<a name="r_WF_COUNT"></a>

 COUNT 窗口函数对由表达式定义的行计数。

COUNT 函数具有两个变体。COUNT(\$1) 对目标表中的所有行计数，无论它们是否包含 null 值。COUNT(expression) 计算某个特定列或表达式中带非 NULL 值的行的数量。

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

```
COUNT ( * | [ ALL ] expression) OVER
(
[ PARTITION BY expr_list ]
[ ORDER BY order_list 
                        frame_clause ]
)
```

## 参数
<a name="r_WF_COUNT-arguments"></a>

 *expression*   
对其执行函数的目标列或表达式。

ALL   
利用参数 ALL，该函数可保留表达式中的所有重复值以进行计数。ALL 是默认值。DISTINCT 不受支持。

OVER   
指定聚合函数的窗口子句。OVER 子句将窗口聚合函数与普通集合聚合函数区分开来。

PARTITION BY *expr\$1list*   
依据一个或多个表达式定义 COUNT 函数的窗口。

ORDER BY *order\$1list*   
对每个分区中的行进行排序。如果未指定 PARTITION BY，则 ORDER BY 使用整个表。

 *frame\$1clause*   
如果 ORDER BY 子句用于聚合函数，则需要显式框架子句。框架子句优化函数窗口中的行集，包含或排除已排序结果中的行集。框架子句包括 ROWS 关键字和关联的说明符。请参阅 [窗口函数语法摘要](c_Window_functions.md#r_Window_function_synopsis)。

## 数据类型
<a name="c_Supported_data_types_wf_count"></a>

COUNT 函数支持所有参数数据类型。

COUNT 函数支持的返回类型是 BIGINT。

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

 以下示例从数据窗口的开头显示销售 ID、数量和所有行的计数：

```
select salesid, qty,
count(*) over (order by salesid rows unbounded preceding) as count
from winsales
order by salesid;

salesid | qty | count
---------+-----+-----
10001 |  10 |   1
10005 |  30 |   2
10006 |  10 |   3
20001 |  20 |   4
20002 |  20 |   5
30001 |  10 |   6
30003 |  15 |   7
30004 |  20 |   8
30007 |  30 |   9
40001 |  40 |   10
40005 |  10 |   11
(11 rows)
```

有关 WINSALES 表的说明，请参阅[窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

以下示例从数据窗口的开头显示销售 ID、数量和非 null 行的计数。（在 WINSALES 表中，QTY\$1SHIPPED 列包含一些 NULL 值。） 

```
select salesid, qty, qty_shipped,
count(qty_shipped)
over (order by salesid rows unbounded preceding) as count
from winsales
order by salesid;

salesid | qty | qty_shipped | count
---------+-----+-------------+-------
10001 |  10 |          10 |   1
10005 |  30 |             |   1
10006 |  10 |             |   1
20001 |  20 |          20 |   2
20002 |  20 |          20 |   3
30001 |  10 |          10 |   4
30003 |  15 |             |   4
30004 |  20 |             |   4
30007 |  30 |             |   4
40001 |  40 |             |   4
40005 |  10 |          10 |   5
(11 rows)
```

# CUME\$1DIST 开窗函数
<a name="r_WF_CUME_DIST"></a>

计算某个窗口或分区中某个值的累积分布。假定升序排序，则使用以下公式确定累积分布：

`count of rows with values <= x / count of rows in the window or partition`

其中，*x* 等于 ORDER BY 子句中指定的列的当前行中的值。以下数据集说明了此公式的使用：

```
Row#	Value	  Calculation    CUME_DIST
1        2500	   (1)/(5)	   0.2
2        2600	   (2)/(5)	   0.4
3        2800	   (3)/(5)	   0.6
4        2900	   (4)/(5)	   0.8
5        3100	   (5)/(5)	   1.0
```

返回值范围介于 0 和 1（含 1）之间。

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

```
CUME_DIST ()
OVER ( 
[ PARTITION BY partition_expression ] 
[ ORDER BY order_list ]
)
```

## 参数
<a name="r_WF_CUME_DIST-arguments"></a>

OVER  
一个指定窗口分区的子句。OVER 子句不能包含窗口框架规范。

PARTITION BY *partition\$1expression*   
可选。一个设置 OVER 子句中每个组的记录范围的表达式。

ORDER BY *order\$1list*   
用于计算累积分布的表达式。该表达式必须具有数字数据类型或可隐式转换为 1。如果省略 ORDER BY，则所有行的返回值为 1。  
如果 ORDER BY 未生成唯一顺序，则行的顺序是不确定的。有关更多信息，请参阅 [窗口函数的唯一数据排序](c_Window_functions.md#r_Examples_order_by_WF)。

## 返回类型
<a name="r_WF_CUME_DIST-returns"></a>

FLOAT8

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

以下示例计算每个卖家的销量的累积分布：

```
select sellerid, qty, cume_dist() 
over (partition by sellerid order by qty) 
from winsales;

sellerid   qty	   cume_dist
--------------------------------------------------
1         10.00	   0.33
1         10.64	   0.67
1         30.37	   1
3         10.04	   0.25
3         15.15	   0.5
3         20.75	   0.75
3         30.55	   1
2         20.09	   0.5
2         20.12	   1
4         10.12	   0.5
4         40.23	   1
```

有关 WINSALES 表的说明，请参阅[窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

# DENSE\$1RANK 窗口函数
<a name="r_WF_DENSE_RANK"></a>

DENSE\$1RANK 窗口函数基于 OVER 子句中的 ORDER BY 表达式确定一组值中的一个值的排名。如果存在可选的 PARTITION BY 子句，则为每个行组重置排名。带符合排名标准的相同值的行接收相同的排名。DENSE\$1RANK 函数与 RANK 存在以下一点不同：如果两个或两个以上的行结合，则一系列排名的值之间没有间隔。例如，如果两个行的排名为 `1`，则下一个排名则为 `2`。

您可以在同一查询中包含带有不同的 PARTITION BY 和 ORDER BY 子句的排名函数。

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

```
DENSE_RANK() OVER
(
[ PARTITION BY expr_list ]
[ ORDER BY order_list ]
)
```

## 参数
<a name="r_WF_DENSE_RANK-arguments"></a>

( )   
该函数没有参数，但需要空括号。

OVER   
适用于 DENSE\$1RANK 函数的窗口子句。

PARTITION BY *expr\$1list*   
（可选）一个或多个用于定义窗口的表达式。

ORDER BY *order\$1list*   
（可选）排名值基于的表达式。如果未指定 PARTITION BY，则 ORDER BY 使用整个表。如果省略 ORDER BY，则所有行的返回值为 `1`。  
如果 ORDER BY 未生成唯一顺序，则行的顺序是不确定的。有关更多信息，请参阅 [窗口函数的唯一数据排序](c_Window_functions.md#r_Examples_order_by_WF)。

## 返回类型
<a name="c_Supported_data_types_wf_dense_rank"></a>

`BIGINT`

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

以下示例使用窗口函数的示例表。有关更多信息，请参阅 [窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

以下示例按销量对表进行排序，并将紧密排名和常规排名分配给每个行。在应用窗口函数结果后，对结果进行排序。

```
SELECT salesid, qty,
DENSE_RANK() OVER(ORDER BY qty DESC) AS d_rnk,
RANK() OVER(ORDER BY qty DESC) AS rnk
FROM winsales
ORDER BY 2,1;

+---------+-----+-------+-----+
| salesid | qty | d_rnk | rnk |
+---------+-----+-------+-----+
|   10001 |  10 |     5 |   8 |
|   10006 |  10 |     5 |   8 |
|   30001 |  10 |     5 |   8 |
|   40005 |  10 |     5 |   8 |
|   30003 |  15 |     4 |   7 |
|   20001 |  20 |     3 |   4 |
|   20002 |  20 |     3 |   4 |
|   30004 |  20 |     3 |   4 |
|   10005 |  30 |     2 |   2 |
|   30007 |  30 |     2 |   2 |
|   40001 |  40 |     1 |   1 |
+---------+-----+-------+-----+
```

在同一查询中一起使用 DENSE\$1RANK 和 RANK 函数时，记下已分配给同一组行的排名的差异。

以下示例按 sellerid 对表进行分区，按数量对每个分区进行排序，并为每个行分配紧密排名。在应用窗口函数结果后，对结果进行排序。

```
SELECT salesid, sellerid, qty,
DENSE_RANK() OVER(PARTITION BY sellerid ORDER BY qty DESC) AS d_rnk
FROM winsales
ORDER BY 2,3,1;

+---------+----------+-----+-------+
| salesid | sellerid | qty | d_rnk |
+---------+----------+-----+-------+
|   10001 |        1 |  10 |     2 |
|   10006 |        1 |  10 |     2 |
|   10005 |        1 |  30 |     1 |
|   20001 |        2 |  20 |     1 |
|   20002 |        2 |  20 |     1 |
|   30001 |        3 |  10 |     4 |
|   30003 |        3 |  15 |     3 |
|   30004 |        3 |  20 |     2 |
|   30007 |        3 |  30 |     1 |
|   40005 |        4 |  10 |     2 |
|   40001 |        4 |  40 |     1 |
+---------+----------+-----+-------+
```

要成功使用上一个示例，请使用以下命令在 WINSALES 表中插入一行。该行与另一行具有相同的 buyerid、sellerid 和 qtysold。这将导致上一个示例中的两行并列，从而显示 DENSE\$1RANK 和 RANK 函数之间的差异。

```
INSERT INTO winsales VALUES(30009, '2/2/2003', 3, 'b', 20, NULL);
```

以下示例按 buyerid 和 sellerid 对表进行分区，按数量对每个分区进行排序，并为每个行分配紧密排名和常规排名。在应用窗口函数后，对结果进行排序。

```
SELECT salesid, sellerid, qty, buyerid,
DENSE_RANK() OVER(PARTITION BY buyerid, sellerid ORDER BY qty DESC) AS d_rnk,
RANK() OVER (PARTITION BY buyerid, sellerid ORDER BY qty DESC) AS rnk
FROM winsales
ORDER BY rnk;

+---------+----------+-----+---------+-------+-----+
| salesid | sellerid | qty | buyerid | d_rnk | rnk |
+---------+----------+-----+---------+-------+-----+
|   20001 |        2 |  20 | b       |     1 |   1 |
|   30007 |        3 |  30 | c       |     1 |   1 |
|   10006 |        1 |  10 | c       |     1 |   1 |
|   10005 |        1 |  30 | a       |     1 |   1 |
|   20002 |        2 |  20 | c       |     1 |   1 |
|   30009 |        3 |  20 | b       |     1 |   1 |
|   40001 |        4 |  40 | a       |     1 |   1 |
|   30004 |        3 |  20 | b       |     1 |   1 |
|   10001 |        1 |  10 | c       |     1 |   1 |
|   40005 |        4 |  10 | a       |     2 |   2 |
|   30003 |        3 |  15 | b       |     2 |   3 |
|   30001 |        3 |  10 | b       |     3 |   4 |
+---------+----------+-----+---------+-------+-----+
```

# FIRST\$1VALUE 窗口函数
<a name="r_WF_first_value"></a>

 在提供一组已排序行的情况下，FIRST\$1VALUE 返回有关窗口框架中的第一行的指定表达式的值。

有关选择框架中最后一行的信息，请参阅 [LAST\$1VALUE 窗口函数](r_WF_last_value.md)。

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

```
FIRST_VALUE( expression )[ IGNORE NULLS | RESPECT NULLS ]
OVER (
[ PARTITION BY expr_list ]
[ ORDER BY order_list frame_clause ]
)
```

## 参数
<a name="r_WF_first_value-arguments"></a>

 *expression*   
 对其执行函数的目标列或表达式。

IGNORE NULLS   
将此选项与 FIRST\$1VALUE 结合使用时，该函数返回不为 NULL 的框架中的第一个值（如果所有值为 NULL，则返回 NULL）。

RESPECT NULLS   
 指示 Amazon Redshift 应包含 null 值以确定要使用的行。如果您未指定 IGNORE NULLS，则默认情况下不支持 RESPECT NULLS。

OVER   
引入函数的窗口子句。

PARTITION BY *expr\$1list*   
依据一个或多个表达式定义函数的窗口。

ORDER BY *order\$1list*   
对每个分区中的行进行排序。如果未指定 PARTITION BY 子句，则 ORDER BY 对整个表进行排序。如果指定 ORDER BY 子句，则还必须指定 *frame\$1clause*。  
FIRST\$1VALUE 函数的结果取决于数据的排序。在以下情况下，结果是不确定的：  
+ 当未指定 ORDER BY 子句且一个分区包含一个表达式的两个不同的值时 
+ 当表达式的计算结果为对应于 ORDER BY 列表中同一值的不同值时。

 *frame\$1clause*   
如果 ORDER BY 子句用于聚合函数，则需要显式框架子句。框架子句优化函数窗口中的行集，包含或排除已排序结果中的行集。框架子句包括 ROWS 关键字和关联的说明符。请参阅[窗口函数语法摘要](c_Window_functions.md#r_Window_function_synopsis)。

## 返回类型
<a name="c_Supported_data_types_wf_first_value"></a>

这些函数支持使用原始 Amazon Redshift 数据类型的表达式。返回类型与 *expression* 的数据类型相同。

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

以下示例使用 TICKIT 样本数据中的 VENUE 表。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

以下示例返回 VENUE 表中每个场地的座位数，同时按容量对结果进行排序（从高到低）。FIRST\$1VALUE 函数用于选择与框架中的第一行对应的场地的名称：在这种情况下，为座位数最多的行。按州对结果进行分区，以便当 VENUESTATE 值发生更改时，会选择一个新的第一个值。窗口框架是无界的，因此为每个分区中的每个行选择相同的第一个值。

对于加利福利亚，`Qualcomm Stadium` 具有最大座位数 (`70561`)，此名称是 `CA` 分区中所有行的第一个值。

```
select venuestate, venueseats, venuename,
first_value(venuename)
over(partition by venuestate
order by venueseats desc
rows between unbounded preceding and unbounded following)
from (select * from venue where venueseats >0)
order by venuestate;

venuestate | venueseats |           venuename            |         first_value
-----------+------------+--------------------------------+------------------------------
CA         |      70561 | Qualcomm Stadium               | Qualcomm Stadium
CA         |      69843 | Monster Park                   | Qualcomm Stadium
CA         |      63026 | McAfee Coliseum                | Qualcomm Stadium
CA         |      56000 | Dodger Stadium                 | Qualcomm Stadium
CA         |      45050 | Angel Stadium of Anaheim       | Qualcomm Stadium
CA         |      42445 | PETCO Park                     | Qualcomm Stadium
CA         |      41503 | AT&T Park                      | Qualcomm Stadium
CA         |      22000 | Shoreline Amphitheatre         | Qualcomm Stadium
CO         |      76125 | INVESCO Field                  | INVESCO Field
CO         |      50445 | Coors Field                    | INVESCO Field
DC         |      41888 | Nationals Park                 | Nationals Park
FL         |      74916 | Dolphin Stadium                | Dolphin Stadium
FL         |      73800 | Jacksonville Municipal Stadium | Dolphin Stadium
FL         |      65647 | Raymond James Stadium          | Dolphin Stadium
FL         |      36048 | Tropicana Field                | Dolphin Stadium
...
```

下面的示例介绍如何使用 IGNORE NULLS 选项，并且事先向 VENUE 表添加一个新行：

```
insert into venue values(2000,null,'Stanford','CA',90000);
```

此新行为 VENUENAME 列包含一个 NULL 值。现在，重复本部分中前面介绍的 FIRST\$1VALUE 查询：

```
select venuestate, venueseats, venuename,
first_value(venuename)
over(partition by venuestate
order by venueseats desc
rows between unbounded preceding and unbounded following)
from (select * from venue where venueseats >0)
order by venuestate;

venuestate | venueseats |         venuename          | first_value
-----------+------------+----------------------------+-------------
CA         |      90000 | NULL                       | NULL
CA         |      70561 | Qualcomm Stadium           | NULL
CA         |      69843 | Monster Park               | NULL
...
```

因为新行包含最高的 VENUESEATS 值 (`90000`) 且其 VENUENAME 为 NULL，所以 FIRST\$1VALUE 函数为 `CA` 分区返回 NULL。要在函数计算中忽略诸如此类的行，请向函数参数添加 IGNORE NULLS 选项：

```
select venuestate, venueseats, venuename,
first_value(venuename) ignore nulls
over(partition by venuestate
order by venueseats desc
rows between unbounded preceding and unbounded following)
from (select * from venue where venuestate='CA')
order by venuestate;

venuestate | venueseats |         venuename          |   first_value
------------+------------+----------------------------+------------------
CA         |      90000 | NULL                       | Qualcomm Stadium
CA         |      70561 | Qualcomm Stadium           | Qualcomm Stadium
CA         |      69843 | Monster Park               | Qualcomm Stadium
...
```

# LAG 窗口函数
<a name="r_WF_LAG"></a>

 LAG 窗口函数返回位于分区中当前行的上方（之前）的某个给定偏移量位置的行的值。

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

```
LAG (value_expr [, offset ])
[ IGNORE NULLS | RESPECT NULLS ]
OVER ( [ PARTITION BY window_partition ] ORDER BY window_ordering )
```

## 参数
<a name="r_WF_LAG-arguments"></a>

 *value\$1expr*   
 对其执行函数的目标列或表达式。

 *offset*   
 一个可选参数，该参数指定要返回其值的当前行前面的行数。偏移量可以是常量整数或计算结果为整数的表达式。如果您未指定偏移量，则 Amazon Redshift 使用 `1` 作为默认值。偏移量为 `0` 表示当前行。

IGNORE NULLS   
一个可选规范，该规范指示 Amazon Redshift 应跳过 null 值以确定要使用的行。如果未列出 IGNORE NULLS，则包含 Null 值。  
您可以使用 NVL 或 COALESCE 表达式将 null 值替换为另一个值。有关更多信息，请参阅 [NVL 和 COALESCE 函数](r_NVL_function.md)。

RESPECT NULLS   
 指示 Amazon Redshift 应包含 null 值以确定要使用的行。如果您未指定 IGNORE NULLS，则默认情况下不支持 RESPECT NULLS。

OVER   
指定窗口分区和排序。OVER 子句不能包含窗口框架规范。

PARTITION BY *window\$1partition*   
一个可选参数，该参数设置 OVER 子句中每个组的记录范围。

ORDER BY *window\$1ordering*   
对每个分区中的行进行排序。

LAG 窗口函数支持使用任何 Amazon Redshift 数据类型的表达式。返回类型与 *value\$1expr* 的类型相同。

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

 以下示例显示已售给买家 ID 为 3 的买家的票数以及买家 3 的购票时间。要将每个销售与买家 3 的上一销售进行比较，查询要返回每个销售的上一销量。由于 1/16/2008 之前未进行购买，则第一个上一销量值为 null：

```
select buyerid, saletime, qtysold,
lag(qtysold,1) over (order by buyerid, saletime) as prev_qtysold
from sales where buyerid = 3 order by buyerid, saletime;

buyerid |      saletime       | qtysold | prev_qtysold
---------+---------------------+---------+--------------
3 | 2008-01-16 01:06:09 |       1 |
3 | 2008-01-28 02:10:01 |       1 |            1
3 | 2008-03-12 10:39:53 |       1 |            1
3 | 2008-03-13 02:56:07 |       1 |            1
3 | 2008-03-29 08:21:39 |       2 |            1
3 | 2008-04-27 02:39:01 |       1 |            2
3 | 2008-08-16 07:04:37 |       2 |            1
3 | 2008-08-22 11:45:26 |       2 |            2
3 | 2008-09-12 09:11:25 |       1 |            2
3 | 2008-10-01 06:22:37 |       1 |            1
3 | 2008-10-20 01:55:51 |       2 |            1
3 | 2008-10-28 01:30:40 |       1 |            2
(12 rows)
```

# LAST\$1VALUE 窗口函数
<a name="r_WF_last_value"></a>

 在提供一组已排序行的情况下，LAST\$1VALUE 函数返回有关框架中最后一行的表达式的值。

有关选择框架中第一行的信息，请参阅 [FIRST\$1VALUE 窗口函数](r_WF_first_value.md)。

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

```
LAST_VALUE( expression )[ IGNORE NULLS | RESPECT NULLS ]
OVER (
[ PARTITION BY expr_list ]
[ ORDER BY order_list frame_clause ]
)
```

## 参数
<a name="r_WF_last_value-arguments"></a>

 *expression*   
 对其执行函数的目标列或表达式。

IGNORE NULLS   
该函数返回不为 NULL 的框架中的最后一个值（如果所有值为 NULL，则返回 NULL）。

RESPECT NULLS   
指示 Amazon Redshift 应包含 null 值以确定要使用的行。如果您未指定 IGNORE NULLS，则默认情况下不支持 RESPECT NULLS。

OVER   
引入函数的窗口子句。

PARTITION BY *expr\$1list*   
依据一个或多个表达式定义函数的窗口。

ORDER BY *order\$1list*   
对每个分区中的行进行排序。如果未指定 PARTITION BY 子句，则 ORDER BY 对整个表进行排序。如果指定 ORDER BY 子句，则还必须指定 *frame\$1clause*。  
结果取决于数据的排序。在以下情况下，结果是不确定的：  
+ 当未指定 ORDER BY 子句且一个分区包含一个表达式的两个不同的值时 
+ 当表达式的计算结果为对应于 ORDER BY 列表中同一值的不同值时。

 *frame\$1clause*   
如果 ORDER BY 子句用于聚合函数，则需要显式框架子句。框架子句优化函数窗口中的行集，包含或排除已排序结果中的行集。框架子句包括 ROWS 关键字和关联的说明符。请参阅[窗口函数语法摘要](c_Window_functions.md#r_Window_function_synopsis)。

## 返回类型
<a name="c_Supported_data_types_wf_last_value"></a>

这些函数支持使用原始 Amazon Redshift 数据类型的表达式。返回类型与 *expression* 的数据类型相同。

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

以下示例使用 TICKIT 样本数据中的 VENUE 表。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

以下示例返回 VENUE 表中每个场地的座位数，同时按容量对结果进行排序（从高到低）。LAST\$1VALUE 函数用于选择与框架中的最后一行对应的场地的名称：在本例中，为座位数最少的行。按州对结果进行分区，以便当 VENUESTATE 值发生更改时，会选择一个新的最后一个值。窗口框架是无界的，因此为每个分区中的每个行选择相同的最后一个值。

对于加利福利亚，为该分区中的每个行返回 `Shoreline Amphitheatre`，因为它具有最小座位数 (`22000`)。

```
select venuestate, venueseats, venuename,
last_value(venuename)
over(partition by venuestate
order by venueseats desc
rows between unbounded preceding and unbounded following)
from (select * from venue where venueseats >0)
order by venuestate;

venuestate | venueseats |           venuename            |          last_value
-----------+------------+--------------------------------+------------------------------
CA         |      70561 | Qualcomm Stadium               | Shoreline Amphitheatre
CA         |      69843 | Monster Park                   | Shoreline Amphitheatre
CA         |      63026 | McAfee Coliseum                | Shoreline Amphitheatre
CA         |      56000 | Dodger Stadium                 | Shoreline Amphitheatre
CA         |      45050 | Angel Stadium of Anaheim       | Shoreline Amphitheatre
CA         |      42445 | PETCO Park                     | Shoreline Amphitheatre
CA         |      41503 | AT&T Park                      | Shoreline Amphitheatre
CA         |      22000 | Shoreline Amphitheatre         | Shoreline Amphitheatre
CO         |      76125 | INVESCO Field                  | Coors Field
CO         |      50445 | Coors Field                    | Coors Field
DC         |      41888 | Nationals Park                 | Nationals Park
FL         |      74916 | Dolphin Stadium                | Tropicana Field
FL         |      73800 | Jacksonville Municipal Stadium | Tropicana Field
FL         |      65647 | Raymond James Stadium          | Tropicana Field
FL         |      36048 | Tropicana Field                | Tropicana Field
...
```

# LEAD 窗口函数
<a name="r_WF_LEAD"></a>

 LEAD 窗口函数返回位于分区中当前行的下方（之后）的某个给定偏移量位置的行的值。

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

```
LEAD (value_expr [, offset ])
[ IGNORE NULLS | RESPECT NULLS ]
OVER ( [ PARTITION BY window_partition ] ORDER BY window_ordering )
```

## 参数
<a name="r_WF_LEAD-arguments"></a>

 *value\$1expr*   
对其执行函数的目标列或表达式。

 *offset*   
 一个可选参数，该参数指定要返回其值的当前行后面的行数。偏移量可以是常量整数或计算结果为整数的表达式。如果您未指定偏移量，则 Amazon Redshift 使用 `1` 作为默认值。偏移量为 `0` 表示当前行。

IGNORE NULLS   
一个可选规范，该规范指示 Amazon Redshift 应跳过 null 值以确定要使用的行。如果未列出 IGNORE NULLS，则包含 Null 值。  
您可以使用 NVL 或 COALESCE 表达式将 null 值替换为另一个值。有关更多信息，请参阅 [NVL 和 COALESCE 函数](r_NVL_function.md)。

RESPECT NULLS   
 指示 Amazon Redshift 应包含 null 值以确定要使用的行。如果您未指定 IGNORE NULLS，则默认情况下不支持 RESPECT NULLS。

OVER   
指定窗口分区和排序。OVER 子句不能包含窗口框架规范。

PARTITION BY *window\$1partition*   
一个可选参数，该参数设置 OVER 子句中每个组的记录范围。

ORDER BY *window\$1ordering*   
对每个分区中的行进行排序。

LEAD 窗口函数支持使用任何 Amazon Redshift 数据类型的表达式。返回类型与 *value\$1expr* 的类型相同。

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

 以下示例提供了 SALES 表中于 2008 年 1 月 1 日与 1 月 2 日已售票的事件的佣金以及为后续销售中售票所付的佣金。以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

```
SELECT eventid, commission, saletime, LEAD(commission, 1) over ( ORDER BY saletime ) AS next_comm
FROM sales
WHERE saletime BETWEEN '2008-01-09 00:00:00' AND '2008-01-10 12:59:59'
LIMIT 10;

+---------+------------+---------------------+-----------+
| eventid | commission |      saletime       | next_comm |
+---------+------------+---------------------+-----------+
|    1664 |       13.2 | 2008-01-09 01:00:21 |      69.6 |
|     184 |       69.6 | 2008-01-09 01:00:36 |     116.1 |
|    6870 |      116.1 | 2008-01-09 01:02:37 |      11.1 |
|    3718 |       11.1 | 2008-01-09 01:05:19 |     205.5 |
|    6772 |      205.5 | 2008-01-09 01:14:04 |      38.4 |
|    3074 |       38.4 | 2008-01-09 01:26:50 |     209.4 |
|    5254 |      209.4 | 2008-01-09 01:29:16 |      26.4 |
|    3724 |       26.4 | 2008-01-09 01:40:09 |      57.6 |
|    5303 |       57.6 | 2008-01-09 01:40:21 |      51.6 |
|    3678 |       51.6 | 2008-01-09 01:42:54 |      43.8 |
+---------+------------+---------------------+-----------+
```

 以下示例提供了 SALES 表中各个活动的佣金与同一活动后续销售的门票销售佣金的最大差异。此示例显示了如何将 LEAD 与 GROUP BY 子句一起使用。由于聚合子句中不支持使用窗口函数，因此该示例使用子查询。以下示例使用 TICKIT 示例数据库。有关更多信息，请参阅 [示例数据库](c_sampledb.md)。

```
SELECT eventid, eventname, max(next_comm_diff) as max_commission_difference
FROM
(
    SELECT sales.eventid, eventname, commission - LEAD(commission, 1) over (ORDER BY sales.eventid, saletime) AS next_comm_diff
    FROM sales JOIN event ON sales.eventid = event.eventid
)
GROUP BY eventid, eventname
ORDER BY eventid

LIMIT 10

| eventid | eventname                   | max_commission_difference |
+---------+-----------------------------+---------------------------+
| 1       | Gotterdammerung             | 7.95                      |
| 2       | Boris Godunov               | 227.85                    |
| 3       | Salome                      | 1350.9                    |
| 4       | La Cenerentola (Cinderella) | 790.05                    |
| 5       | Il Trovatore                | 214.05                    |
| 6       | L Elisir d Amore            | 510.9                     |
| 7       | Doctor Atomic               | 180.6                     |
| 9       | The Fly                     | 147                       |
| 10      | Rigoletto                   | 186.6                     |
+---------+-----------------------------+---------------------------+
```

# LISTAGG 窗口函数
<a name="r_WF_LISTAGG"></a>

对于查询中的每个组，LISTAGG 窗口函数根据 ORDER BY 表达式对该组的行进行排序，然后将值串联成一个字符串。

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

```
LISTAGG( [DISTINCT] expression [, 'delimiter' ] ) 
[ WITHIN GROUP (ORDER BY order_list) ] 
OVER ( [PARTITION BY partition_expression] )
```

## 参数
<a name="r_WF_LISTAGG-arguments"></a>

DISTINCT  
（可选）用于在串联之前消除指定表达式中重复值的子句。尾部空格将被忽略，因此会将字符串 `'a'` 和 `'a '` 视为重复值。LISTAGG 将使用遇到的第一个值。有关更多信息，请参阅 [尾部空格的意义](r_Character_types.md#r_Character_types-significance-of-trailing-blanks)。

  


*aggregate\$1expression*   
 提供要聚合的值的任何有效表达式（如列名称）。忽略 NULL 值和空字符串。

 *分隔符*   
（可选）将用于分隔串联的值的字符串常数。默认值为 NULL。

 WITHIN GROUP (ORDER BY *order\$1list*)   
（可选）用于指定聚合值的排序顺序的子句。仅在 ORDER BY 提供唯一排序时是确定性的。默认为聚合所有行并返回一个值。

 OVER   
 一个指定窗口分区的子句。OVER 子句不能包含窗口排序或窗口框架规范。

 PARTITION BY *partition\$1expression*   
（可选）设置 OVER 子句中每个组的记录范围。

## 返回值
<a name="r_WF_LISTAGG-data-types"></a>

如果结果集超过 1600 万个字节，则 LISTAGG 返回以下错误：

```
Invalid operation: Result size exceeds LISTAGG limit
```

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

以下示例使用 WINSALES 表。有关 WINSALES 表的说明，请参阅[窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

以下示例返回卖家 ID 的列表（按卖家 ID 排序）。

```
select listagg(sellerid) 
within group (order by sellerid)
over() from winsales;

  listagg
------------
 11122333344
...
...
 11122333344
 11122333344
   (11 rows)
```

以下示例返回买家 B 的卖家 ID 的列表（按日期排序）。

```
select listagg(sellerid) 
within group (order by dateid)
over () as seller
from winsales
where buyerid = 'b' ;

  seller
---------
    3233
    3233
    3233
    3233
```

以下示例返回买家 B 的销售日期的逗号分隔的列表。

```
select listagg(dateid,',') 
within group (order by sellerid desc,salesid asc)
over () as dates
from winsales
where buyerid  = 'b';

             dates                                      
-------------------------------------------
2003-08-02,2004-04-18,2004-04-18,2004-02-12
2003-08-02,2004-04-18,2004-04-18,2004-02-12
2003-08-02,2004-04-18,2004-04-18,2004-02-12
2003-08-02,2004-04-18,2004-04-18,2004-02-12
```

以下示例使用 DISTINCT 返回买家 B 的唯一销售日期的列表。

```
select listagg(distinct dateid,',') 
within group (order by sellerid desc,salesid asc)
over () as dates
from winsales
where buyerid  = 'b';

           dates
--------------------------------
2003-08-02,2004-04-18,2004-02-12
2003-08-02,2004-04-18,2004-02-12
2003-08-02,2004-04-18,2004-02-12
2003-08-02,2004-04-18,2004-02-12
```

以下示例返回每个买家 ID 的销售 ID 的逗号分隔的列表。

```
select buyerid, 
listagg(salesid,',')
within group (order by salesid)
over (partition by buyerid) as sales_id
from winsales
order by buyerid;

+---------+-------------------------+
| buyerid |        sales_id         |
+---------+-------------------------+
| a       | 10005,40001,40005       |
| a       | 10005,40001,40005       |
| a       | 10005,40001,40005       |
| b       | 20001,30001,30003,30004 |
| b       | 20001,30001,30003,30004 |
| b       | 20001,30001,30003,30004 |
| b       | 20001,30001,30003,30004 |
| c       | 10001,10006,20002,30007 |
| c       | 10001,10006,20002,30007 |
| c       | 10001,10006,20002,30007 |
| c       | 10001,10006,20002,30007 |
+---------+-------------------------+
```

以下示例演示 LISTAGG 对最多 1600 万个字节的连接结果的支持：

```
CREATE TABLE large_data (
    id INT,
    content VARCHAR(65535)
);

INSERT INTO large_data VALUES 
    (1, REPEAT('A', 65535)),
    (2, REPEAT('B', 65535)),
    (3, REPEAT('C', 65535));

SELECT LEN(LISTAGG(content, ',') WITHIN GROUP (ORDER BY id)) AS total_length
FROM large_data;

 total_length
--------------
       196607
```

# MAX 窗口函数
<a name="r_WF_MAX"></a>

 MAX 窗口函数返回最大输入表达式值。MAX 函数使用数值并忽略 NULL 值。

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

```
MAX ( [ ALL ] expression ) OVER
(
[ PARTITION BY expr_list ]
[ ORDER BY order_list frame_clause ]
)
```

## 参数
<a name="r_WF_MAX-arguments"></a>

 *expression*   
对其执行函数的目标列或表达式。

ALL   
利用参数 ALL，该函数可保留表达式中的所有重复值。ALL 是默认值。DISTINCT 不受支持。

OVER   
 一个指定聚合函数的窗口子句的子句。OVER 子句将窗口聚合函数与普通集合聚合函数区分开来。

PARTITION BY *expr\$1list*   
依据一个或多个表达式定义 MAX 函数的窗口。

ORDER BY *order\$1list*   
对每个分区中的行进行排序。如果未指定 PARTITION BY，则 ORDER BY 使用整个表。

 *frame\$1clause*   
如果 ORDER BY 子句用于聚合函数，则需要显式框架子句。框架子句优化函数窗口中的行集，包含或排除已排序结果中的行集。框架子句包括 ROWS 关键字和关联的说明符。请参阅 [窗口函数语法摘要](c_Window_functions.md#r_Window_function_synopsis)。

## 数据类型
<a name="r_WF_MAX-data-types"></a>

接受任何数据类型作为输入。返回与 *expression* 相同的数据类型。

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

以下示例从数据窗口的开头显示销售 ID、数量和最大数量：

```
select salesid, qty,
max(qty) over (order by salesid rows unbounded preceding) as max
from winsales
order by salesid;

salesid | qty | max
---------+-----+-----
10001 |  10 |  10
10005 |  30 |  30
10006 |  10 |  30
20001 |  20 |  30
20002 |  20 |  30
30001 |  10 |  30
30003 |  15 |  30
30004 |  20 |  30
30007 |  30 |  30
40001 |  40 |  40
40005 |  10 |  40
(11 rows)
```

有关 WINSALES 表的说明，请参阅[窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

以下示例在受限制的框架中显示销售 ID、数量和最大数量：

```
select salesid, qty,
max(qty) over (order by salesid rows between 2 preceding and 1 preceding) as max
from winsales
order by salesid;

salesid | qty | max
---------+-----+-----
10001 |  10 |
10005 |  30 |  10
10006 |  10 |  30
20001 |  20 |  30
20002 |  20 |  20
30001 |  10 |  20
30003 |  15 |  20
30004 |  20 |  15
30007 |  30 |  20
40001 |  40 |  30
40005 |  10 |  40
(11 rows)
```

# MEDIAN 开窗函数
<a name="r_WF_MEDIAN"></a>

计算某个窗口或分区中值的范围的中间值。忽略该范围中的 NULL 值。

MEDIAN 是一种假定连续分布模型的逆分布函数。

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

```
MEDIAN ( median_expression )
OVER ( [ PARTITION BY partition_expression ] )
```

## 参数
<a name="r_WF_MEDIAN-arguments"></a>

 *median\$1expression*   
一个提供要为其确定中间值的值的表达式（例如列名）。该表达式必须具有数字数据类型或日期时间数据类型或可隐式转换为 1。

OVER   
一个指定窗口分区的子句。OVER 子句不能包含窗口排序或窗口框架规范。

PARTITION BY *partition\$1expression*   
可选。一个设置 OVER 子句中每个组的记录范围的表达式。

## 数据类型
<a name="r_WF_MEDIAN-data-types"></a>

返回类型由 *median\$1expression* 的数据类型确定。下表显示了每种 *median\$1expression* 数据类型的返回类型。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_WF_MEDIAN.html)

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

如果 *median\$1expression* 参数是使用 38 位最大精度定义的 DECIMAL 数据类型，则 MEDIAN 可能将返回不准确的结果或错误。如果 MEDIAN 函数的返回值超过 38 位，则结果将截断以符合规范，这将导致精度降低。如果在插值期间，中间结果超出最大精度，则会发生数值溢出且函数会返回错误。要避免这些情况，建议使用具有较低精度的数据类型或将 *median\$1expression* 参数转换为较低精度。

例如，带 DECIMAL 参数的 SUM 函数返回 38 位的默认精度。结果的小数位数与参数的小数位数相同。因此，例如，DECIMAL(5,2) 列的 SUM 返回 DECIMAL(38,2) 数据类型。

以下示例在 MEDIAN 函数的 *median\$1expression* 参数中使用 SUM 函数。PRICEPAID 列的数据类型是 DECIMAL (8,2)，因此 SUM 函数返回 DECIMAL(38,2)。

```
select salesid, sum(pricepaid), median(sum(pricepaid)) 
over() from sales where salesid < 10 group by salesid;
```

要避免潜在的精度降低或溢出错误，请将结果转换为具有较低精度的 DECIMAL 数据类型，如以下示例所示。

```
select salesid, sum(pricepaid), median(sum(pricepaid)::decimal(30,2)) 
over() from sales where salesid < 10 group by salesid;
```

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

 以下示例计算每个卖家的平均销售数量：

```
select sellerid, qty, median(qty) 
over (partition by sellerid) 
from winsales
order by sellerid;


sellerid	qty	median
---------------------------
1		10	10.0
1		10	10.0
1		30	10.0
2		20	20.0
2		20	20.0
3		10	17.5
3		15	17.5
3		20	17.5
3		30	17.5
4		10	25.0
4		40	25.0
```

有关 WINSALES 表的说明，请参阅[窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

# MIN 窗口函数
<a name="r_WF_MIN"></a>

 MIN 窗口函数返回最小输入表达式值。MIN 函数使用数值并忽略 NULL 值。

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

```
MIN ( [ ALL ] expression ) OVER
(
[ PARTITION BY expr_list ]
[ ORDER BY order_list frame_clause ]
)
```

## 参数
<a name="r_WF_MIN-arguments"></a>

 *expression*   
对其执行函数的目标列或表达式。

ALL   
利用参数 ALL，该函数可保留表达式中的所有重复值。ALL 是默认值。DISTINCT 不受支持。

OVER   
指定聚合函数的窗口子句。OVER 子句将窗口聚合函数与普通集合聚合函数区分开来。

PARTITION BY *expr\$1list*   
依据一个或多个表达式定义 MIN 函数的窗口。

ORDER BY *order\$1list*   
对每个分区中的行进行排序。如果未指定 PARTITION BY，则 ORDER BY 使用整个表。

 *frame\$1clause*   
如果 ORDER BY 子句用于聚合函数，则需要显式框架子句。框架子句优化函数窗口中的行集，包含或排除已排序结果中的行集。框架子句包括 ROWS 关键字和关联的说明符。请参阅 [窗口函数语法摘要](c_Window_functions.md#r_Window_function_synopsis)。

## 数据类型
<a name="r_WF_MIN-data-types"></a>

接受任何数据类型作为输入。返回与 *expression* 相同的数据类型。

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

以下示例从数据窗口的开头显示销售 ID、数量和最小数量：

```
select salesid, qty,
min(qty) over
(order by salesid rows unbounded preceding)
from winsales
order by salesid;

salesid | qty | min
---------+-----+-----
10001 |  10 |  10
10005 |  30 |  10
10006 |  10 |  10
20001 |  20 |  10
20002 |  20 |  10
30001 |  10 |  10
30003 |  15 |  10
30004 |  20 |  10
30007 |  30 |  10
40001 |  40 |  10
40005 |  10 |  10
(11 rows)
```

 有关 WINSALES 表的说明，请参阅[窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

以下示例在受限制的框架中显示销售 ID、数量和最小数量：

```
select salesid, qty,
min(qty) over
(order by salesid rows between 2 preceding and 1 preceding) as min
from winsales
order by salesid;

salesid | qty | min
---------+-----+-----
10001 |  10 |
10005 |  30 |  10
10006 |  10 |  10
20001 |  20 |  10
20002 |  20 |  10
30001 |  10 |  20
30003 |  15 |  10
30004 |  20 |  10
30007 |  30 |  15
40001 |  40 |  20
40005 |  10 |  30
(11 rows)
```

# NTH\$1VALUE 窗口函数
<a name="r_WF_NTH"></a>

 NTH\$1VALUE 窗口函数返回相对于窗口的第一行的窗口框架的指定行的表达式值。

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

```
NTH_VALUE (expr, offset)
[ IGNORE NULLS | RESPECT NULLS ]
OVER
( [ PARTITION BY window_partition ]
[ ORDER BY window_ordering 
                        frame_clause ] )
```

## 参数
<a name="r_WF_NTH-arguments"></a>

 *expr*   
 对其执行函数的目标列或表达式。

 *offset*   
 确定相对于要为其返回表达式的窗口中的第一行的行号。*offset* 可以是常数或表达式，且必须为大于 0 的正整数。

IGNORE NULLS   
一个可选规范，该规范指示 Amazon Redshift 应跳过 null 值以确定要使用的行。如果未列出 IGNORE NULLS，则包含 Null 值。

RESPECT NULLS   
 指示 Amazon Redshift 应包含 null 值以确定要使用的行。如果您未指定 IGNORE NULLS，则默认情况下不支持 RESPECT NULLS。

OVER   
指定窗口分区、排序和窗口框架。

PARTITION BY *window\$1partition*   
设置 OVER 子句中每个组的记录范围。

ORDER BY *window\$1ordering*   
对每个分区中的行进行排序。如果忽略 ORDER BY，则默认框架将包含分区中的所有行。

 *frame\$1clause*   
如果 ORDER BY 子句用于聚合函数，则需要显式框架子句。框架子句优化函数窗口中的行集，包含或排除已排序结果中的行集。框架子句包括 ROWS 关键字和关联的说明符。请参阅 [窗口函数语法摘要](c_Window_functions.md#r_Window_function_synopsis)。

NTH\$1VALUE 窗口函数支持使用任何 Amazon Redshift 数据类型的表达式。返回类型与 *expr* 的类型相同。

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

以下示例显示了加利福利亚、佛罗里达和纽约的第三大场地的座位数与这些州的其他场地的座位数的比较情况：

```
select venuestate, venuename, venueseats,
nth_value(venueseats, 3)
ignore nulls
over(partition by venuestate order by venueseats desc
rows between unbounded preceding and unbounded following)
as third_most_seats
from (select * from venue where venueseats > 0 and
venuestate in('CA', 'FL', 'NY'))
order by venuestate;

venuestate |           venuename            | venueseats | third_most_seats
------------+--------------------------------+------------+------------------
CA         | Qualcomm Stadium               |      70561 |            63026
CA         | Monster Park                   |      69843 |            63026
CA         | McAfee Coliseum                |      63026 |            63026
CA         | Dodger Stadium                 |      56000 |            63026
CA         | Angel Stadium of Anaheim       |      45050 |            63026
CA         | PETCO Park                     |      42445 |            63026
CA         | AT&T Park                      |      41503 |            63026
CA         | Shoreline Amphitheatre         |      22000 |            63026
FL         | Dolphin Stadium                |      74916 |            65647
FL         | Jacksonville Municipal Stadium |      73800 |            65647
FL         | Raymond James Stadium          |      65647 |            65647
FL         | Tropicana Field                |      36048 |            65647
NY         | Ralph Wilson Stadium           |      73967 |            20000
NY         | Yankee Stadium                 |      52325 |            20000
NY         | Madison Square Garden          |      20000 |            20000
(15 rows)
```

# NTILE 窗口函数
<a name="r_WF_NTILE"></a>

 NTILE 窗口函数将分区中已排序的行划分为大小尽可能相等的指定数量的已排名组，并返回给定行所在的组。

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

```
NTILE (expr)
OVER ( 
[ PARTITION BY expression_list ] 
[ ORDER BY order_list ]
)
```

## 参数
<a name="r_WF_NTILE-arguments"></a>

 *expr*   
排名组的数目，并且必须为每个分区生成一个正整数值（大于零）。*expr* 参数不得可为 null。

OVER   
 一个指定窗口分区和排序的子句。OVER 子句不能包含窗口框架规范。

PARTITION BY *window\$1partition*   
可选。OVER 子句中每个组的记录范围。

ORDER BY *window\$1ordering*   
可选。一个对每个分区中的行进行排序的表达式。如果忽略 ORDER BY 子句，则排名行为相同。  
如果 ORDER BY 未生成唯一顺序，则行的顺序是不确定的。有关更多信息，请参阅 [窗口函数的唯一数据排序](c_Window_functions.md#r_Examples_order_by_WF)。

## 返回类型
<a name="r_WF_NTILE-return-type"></a>

BIGINT

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

 以下示例将于 2008 年 8 月 26 日购买 Hamlet 门票所付价格划分到四个排名组中。结果集为 17 个行，几乎均匀地划分到排名 1 到 4 中：

```
select eventname, caldate, pricepaid, ntile(4)
over(order by pricepaid desc) from sales, event, date
where sales.eventid=event.eventid and event.dateid=date.dateid and eventname='Hamlet'
and caldate='2008-08-26'
order by 4;

eventname |  caldate   | pricepaid | ntile
-----------+------------+-----------+-------
Hamlet    | 2008-08-26 |   1883.00 |     1
Hamlet    | 2008-08-26 |   1065.00 |     1
Hamlet    | 2008-08-26 |    589.00 |     1
Hamlet    | 2008-08-26 |    530.00 |     1
Hamlet    | 2008-08-26 |    472.00 |     1
Hamlet    | 2008-08-26 |    460.00 |     2
Hamlet    | 2008-08-26 |    355.00 |     2
Hamlet    | 2008-08-26 |    334.00 |     2
Hamlet    | 2008-08-26 |    296.00 |     2
Hamlet    | 2008-08-26 |    230.00 |     3
Hamlet    | 2008-08-26 |    216.00 |     3
Hamlet    | 2008-08-26 |    212.00 |     3
Hamlet    | 2008-08-26 |    106.00 |     3
Hamlet    | 2008-08-26 |    100.00 |     4
Hamlet    | 2008-08-26 |     94.00 |     4
Hamlet    | 2008-08-26 |     53.00 |     4
Hamlet    | 2008-08-26 |     25.00 |     4
(17 rows)
```

# PERCENT\$1RANK 开窗函数
<a name="r_WF_PERCENT_RANK"></a>

计算给定行的百分比排名。使用以下公式确定百分比排名：

`(x - 1) / (the number of rows in the window or partition - 1)`

其中，*x* 为当前行的排名。以下数据集说明了此公式的使用：

```
Row#	Value	Rank	Calculation	PERCENT_RANK
1	15	1	(1-1)/(7-1)	0.0000
2	20	2	(2-1)/(7-1)	0.1666
3	20	2	(2-1)/(7-1)	0.1666
4	20	2	(2-1)/(7-1)	0.1666
5	30	5	(5-1)/(7-1)	0.6666
6	30	5	(5-1)/(7-1)	0.6666
7	40	7	(7-1)/(7-1)	1.0000
```

返回值范围介于 0 和 1（含 1）之间。任何集合中的第一行的 PERCENT\$1RANK 均为 0。

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

```
PERCENT_RANK ()
OVER ( 
[ PARTITION BY partition_expression ] 
[ ORDER BY order_list ]
)
```

## 参数
<a name="r_WF_PERCENT_RANK-arguments"></a>

( )   
该函数没有参数，但需要空括号。

OVER  
一个指定窗口分区的子句。OVER 子句不能包含窗口框架规范。

PARTITION BY *partition\$1expression*   
可选。一个设置 OVER 子句中每个组的记录范围的表达式。

ORDER BY *order\$1list*   
可选。用于计算百分比排名的表达式。该表达式必须具有数字数据类型或可隐式转换为 1。如果省略 ORDER BY，则所有行的返回值为 0。  
如果 ORDER BY 未生成唯一顺序，则行的顺序是不确定的。有关更多信息，请参阅 [窗口函数的唯一数据排序](c_Window_functions.md#r_Examples_order_by_WF)。

## 返回类型
<a name="r_WF_PERCENT_RANK-return-type"></a>

FLOAT8

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

以下示例计算每个卖家的销售数量的百分比排名：

```
select sellerid, qty, percent_rank() 
over (partition by sellerid order by qty) 
from winsales;

sellerid	qty		percent_rank
----------------------------------------
1		10.00		0.0
1		10.64		0.5
1		30.37		1.0
3		10.04		0.0
3		15.15		0.33
3		20.75		0.67
3		30.55		1.0
2		20.09		0.0
2		20.12		1.0
4		10.12		0.0
4		40.23		1.0
```

有关 WINSALES 表的说明，请参阅[窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

# PERCENTILE\$1CONT 开窗函数
<a name="r_WF_PERCENTILE_CONT"></a>

PERCENTILE\$1CONT 是一种假定连续分布模型的逆分布函数。该函数具有一个百分比值和一个排序规范，并返回一个在有关排序规范的给定百分比值范围内的内插值。

PERCENTILE\$1CONT 在对值进行排序后计算值之间的线性内插。通过在聚合组中使用百分比值 `(P)` 和非 null 行数 `(N)`，该函数会在根据排序规范对行进行排序后计算行号。根据公式 `(RN)` 计算此行号 `RN = (1+ (P*(N-1))`。聚合函数的最终结果通过行号 `CRN = CEILING(RN)` 和 `FRN = FLOOR(RN)` 的行中的值之间的线性内插计算。

最终结果将如下所示。

如果 `(CRN = FRN = RN)`，则结果为 `(value of expression from row at RN)` 

否则，结果将如下所示：

`(CRN - RN) * (value of expression for row at FRN) + (RN - FRN) * (value of expression for row at CRN)`.

您在 OVER 子句中只能指定 PARTITION 子句。如果为每个行指定 PARTITION，则 PERCENTILE\$1CONT 会返回位于给定分区内一组值中的指定百分比范围内的值。

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

```
PERCENTILE_CONT ( percentile )
WITHIN GROUP (ORDER BY expr)
OVER (  [ PARTITION BY expr_list ]  )
```

## 参数
<a name="r_WF_PERCENTILE_CONT-arguments"></a>

 *percentile*   
介于 0 和 1 之间的数字常数。计算中将忽略 Null。

WITHIN GROUP ( ORDER BY *expr*)   
指定用于排序和计算百分比的数字或日期/时间值。

OVER   
指定窗口分区。OVER 子句不能包含窗口排序或窗口框架规范。

PARTITION BY *expr*   
设置 OVER 子句中每个组的记录范围的可选参数。

## 返回值
<a name="r_WF_PERCENTILE_CONT-returns"></a>

返回类型由 WITHIN GROUP 子句中的 ORDER BY 表达式的数据类型决定。下表显示了每种个 ORDER BY 表达式数据类型的返回类型。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_WF_PERCENTILE_CONT.html)

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

如果 ORDER BY 表达式是使用 38 位最大精度定义的 DECIMAL 数据类型，则 PERCENTILE\$1CONT 可能将返回不准确的结果或错误。如果 PERCENTILE\$1CONT 函数的返回值超过 38 位，则结果将截断以符合规范，这将导致精度降低。如果在插值期间，中间结果超出最大精度，则会发生数值溢出且函数会返回错误。要避免这些情况，建议使用具有较低精度的数据类型或将 ORDER BY 表达式转换为较低精度。

例如，带 DECIMAL 参数的 SUM 函数返回 38 位的默认精度。结果的小数位数与参数的小数位数相同。因此，例如，DECIMAL(5,2) 列的 SUM 返回 DECIMAL(38,2) 数据类型。

以下示例在 PERCENTILE\$1CONT 函数的 ORDER BY 子句中使用 SUM 函数。PRICEPAID 列的数据类型是 DECIMAL (8,2)，因此 SUM 函数返回 DECIMAL(38,2)。

```
select salesid, sum(pricepaid), percentile_cont(0.6) 
within group (order by sum(pricepaid) desc) over()
from sales where salesid < 10 group by salesid;
```

要避免潜在的精度降低或溢出错误，请将结果转换为具有较低精度的 DECIMAL 数据类型，如以下示例所示。

```
select salesid, sum(pricepaid), percentile_cont(0.6) 
within group (order by sum(pricepaid)::decimal(30,2) desc) over()
from sales where salesid < 10 group by salesid;
```

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

以下示例使用 WINSALES 表。有关 WINSALES 表的说明，请参阅[窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

```
select sellerid, qty, percentile_cont(0.5) 
within group (order by qty) 
over() as median from winsales;

 sellerid | qty | median 
----------+-----+--------
        1 |  10 |   20.0
        1 |  10 |   20.0
        3 |  10 |   20.0
        4 |  10 |   20.0
        3 |  15 |   20.0
        2 |  20 |   20.0
        3 |  20 |   20.0
        2 |  20 |   20.0
        3 |  30 |   20.0
        1 |  30 |   20.0
        4 |  40 |   20.0
(11 rows)
```

```
select sellerid, qty, percentile_cont(0.5) 
within group (order by qty) 
over(partition by sellerid) as median from winsales;

 sellerid | qty | median 
----------+-----+--------
        2 |  20 |   20.0
        2 |  20 |   20.0
        4 |  10 |   25.0
        4 |  40 |   25.0
        1 |  10 |   10.0
        1 |  10 |   10.0
        1 |  30 |   10.0
        3 |  10 |   17.5
        3 |  15 |   17.5
        3 |  20 |   17.5
        3 |  30 |   17.5
(11 rows)
```

以下示例计算华盛顿州的卖家的门票销售的 PERCENTILE\$1CONT 和 PERCENTILE\$1DISC。

```
SELECT sellerid, state, sum(qtysold*pricepaid) sales, 
percentile_cont(0.6) within group (order by sum(qtysold*pricepaid::decimal(14,2) ) desc) over(),
percentile_disc(0.6) within group (order by sum(qtysold*pricepaid::decimal(14,2) ) desc) over()
from sales s, users u 
where s.sellerid = u.userid and state = 'WA' and sellerid < 1000
group by sellerid, state;

 sellerid | state |  sales  | percentile_cont | percentile_disc
----------+-------+---------+-----------------+-----------------
      127 | WA    | 6076.00 |         2044.20 |         1531.00
      787 | WA    | 6035.00 |         2044.20 |         1531.00
      381 | WA    | 5881.00 |         2044.20 |         1531.00
      777 | WA    | 2814.00 |         2044.20 |         1531.00
       33 | WA    | 1531.00 |         2044.20 |         1531.00
      800 | WA    | 1476.00 |         2044.20 |         1531.00
        1 | WA    | 1177.00 |         2044.20 |         1531.00
(7 rows)
```

# PERCENTILE\$1DISC 开窗函数
<a name="r_WF_PERCENTILE_DISC"></a>

PERCENTILE\$1DISC 是一种假定离散分布模型的逆分布函数。该函数具有一个百分比值和一个排序规范，并返回给定集合中的元素。

对于给定的百分比值 P，PERCENTILE\$1DISC 在 ORDER BY 子句中对表达式的值进行排序，并返回带有大于或等于 P 的最小累积分布值（相对于同一排序规范）的值。

您在 OVER 子句中只能指定 PARTITION 子句。

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

```
PERCENTILE_DISC ( percentile )
WITHIN GROUP (ORDER BY expr)
OVER (  [ PARTITION BY expr_list ]  )
```

## 参数
<a name="r_WF_PERCENTILE_DISC-arguments"></a>

 *percentile*   
介于 0 和 1 之间的数字常数。计算中将忽略 Null。

WITHIN GROUP ( ORDER BY *expr*)   
指定用于排序和计算百分比的数字或日期/时间值。

OVER   
指定窗口分区。OVER 子句不能包含窗口排序或窗口框架规范。

PARTITION BY *expr*   
设置 OVER 子句中每个组的记录范围的可选参数。

## 返回值
<a name="r_WF_PERCENTILE_DISC-returns"></a>

与 WITHIN GROUP 子句中的 ORDER BY 表达式相同的数据类型。

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

以下各示例使用 WINSALES 表。有关 WINSALES 表的说明，请参阅[窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

```
SELECT sellerid, qty, PERCENTILE_DISC(0.5) 
WITHIN GROUP (ORDER BY qty) 
OVER() AS MEDIAN FROM winsales;

+----------+-----+--------+
| sellerid | qty | median |
+----------+-----+--------+
| 3        | 10  | 20     |
| 1        | 10  | 20     |
| 1        | 10  | 20     |
| 4        | 10  | 20     |
| 3        | 15  | 20     |
| 2        | 20  | 20     |
| 2        | 20  | 20     |
| 3        | 20  | 20     |
| 1        | 30  | 20     |
| 3        | 30  | 20     |
| 4        | 40  | 20     |
+----------+-----+--------+

SELECT sellerid, qty, PERCENTILE_DISC(0.5) 
WITHIN GROUP (ORDER BY qty) 
OVER(PARTITION BY sellerid) AS MEDIAN FROM winsales;

+----------+-----+--------+
| sellerid | qty | median |
+----------+-----+--------+
| 4        | 10  | 10     |
| 4        | 40  | 10     |
| 3        | 10  | 15     |
| 3        | 15  | 15     |
| 3        | 20  | 15     |
| 3        | 30  | 15     |
| 2        | 20  | 20     |
| 2        | 20  | 20     |
| 1        | 10  | 10     |
| 1        | 10  | 10     |
| 1        | 30  | 10     |
+----------+-----+--------+
```

要在按卖家 ID 分区时为数量找到 PERCENTILE\$1DISC(0.25) 和 PERCENTILE\$1DISC(0.75)，请使用以下示例。

```
SELECT sellerid, qty, PERCENTILE_DISC(0.25) 
WITHIN GROUP (ORDER BY qty) 
OVER(PARTITION BY sellerid) AS quartile1 FROM winsales;

+----------+-----+-----------+
| sellerid | qty | quartile1 |
+----------+-----+-----------+
| 4        | 10  | 10        |
| 4        | 40  | 10        |
| 2        | 20  | 20        |
| 2        | 20  | 20        |
| 3        | 10  | 10        |
| 3        | 15  | 10        |
| 3        | 20  | 10        |
| 3        | 30  | 10        |
| 1        | 10  | 10        |
| 1        | 10  | 10        |
| 1        | 30  | 10        |
+----------+-----+-----------+

SELECT sellerid, qty, PERCENTILE_DISC(0.75) 
WITHIN GROUP (ORDER BY qty) 
OVER(PARTITION BY sellerid) AS quartile3 FROM winsales;

+----------+-----+-----------+
| sellerid | qty | quartile3 |
+----------+-----+-----------+
| 3        | 10  | 20        |
| 3        | 15  | 20        |
| 3        | 20  | 20        |
| 3        | 30  | 20        |
| 4        | 10  | 40        |
| 4        | 40  | 40        |
| 2        | 20  | 20        |
| 2        | 20  | 20        |
| 1        | 10  | 30        |
| 1        | 10  | 30        |
| 1        | 30  | 30        |
+----------+-----+-----------+
```

# RANK 窗口函数
<a name="r_WF_RANK"></a>

 RANK 窗口函数基于 OVER 子句中的 ORDER BY 表达式确定一组值中的一个值的排名。如果存在可选的 PARTITION BY 子句，则为每个行组重置排名。带符合排名标准的相同值的行接收相同的排名。Amazon Redshift 将关联行的数目添加到关联排名以计算下一个排名，因此排名可能不是连续数。例如，如果两个行的排名为 1，则下一个排名则为 3。

 RANK 与 [DENSE\$1RANK 窗口函数](r_WF_DENSE_RANK.md)存在以下一点不同：对于 DENSE\$1RANK 来说，如果两个或两个以上的行结合，则一系列排名的值之间没有间隔。例如，如果两个行的排名为 1，则下一个排名则为 2。

您可以在同一查询中包含带有不同的 PARTITION BY 和 ORDER BY 子句的排名函数。

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

```
RANK () OVER
(
[ PARTITION BY expr_list ]
[ ORDER BY order_list ]
)
```

## 参数
<a name="r_WF_RANK-arguments"></a>

( )   
该函数没有参数，但需要空括号。

OVER   
适用于 RANK 函数的窗口子句。

PARTITION BY *expr\$1list*   
可选。一个或多个定义窗口的表达式。

ORDER BY *order\$1list*   
可选。定义排名值基于的列。如果未指定 PARTITION BY，则 ORDER BY 使用整个表。如果省略 ORDER BY，则所有行的返回值为 1。  
如果 ORDER BY 未生成唯一顺序，则行的顺序是不确定的。有关更多信息，请参阅 [窗口函数的唯一数据排序](c_Window_functions.md#r_Examples_order_by_WF)。

## 返回类型
<a name="c_Supported_data_types_wf_rank"></a>

INTEGER

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

以下示例按销量对表进行排序（预设情况下按升序顺序），并为每个行分配一个排名。排名值 1 为排名最高的值。在应用窗口函数结果后，对结果进行排序：

```
select salesid, qty,
rank() over (order by qty) as rnk
from winsales
order by 2,1;

salesid | qty | rnk
--------+-----+-----
10001 |  10 |  1
10006 |  10 |  1
30001 |  10 |  1
40005 |  10 |  1
30003 |  15 |  5
20001 |  20 |  6
20002 |  20 |  6
30004 |  20 |  6
10005 |  30 |  9
30007 |  30 |  9
40001 |  40 |  11
(11 rows)
```

请注意，本示例中的外部 ORDER BY 子句包括列 2 和列 1，以确保在每次运行查询时，Amazon Redshift 返回一致排序的结果。例如，销售 ID 为 10001 和 10006 的行具有相同的 QTY 和 RNK 值。按列 1 对最后的结果集进行排序可确保行 10001 始终在 10006 之前。有关 WINSALES 表的说明，请参阅[窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

在下面的示例中，将窗口函数的顺序倒转 (`order by qty desc`)。现在，最高排名值将应用于最大的 QTY 值。

```
select salesid, qty,
rank() over (order by qty desc) as rank
from winsales
order by 2,1;

 salesid | qty | rank
---------+-----+-----
   10001 |  10 |   8
   10006 |  10 |   8
   30001 |  10 |   8
   40005 |  10 |   8
   30003 |  15 |   7
   20001 |  20 |   4
   20002 |  20 |   4
   30004 |  20 |   4
   10005 |  30 |   2
   30007 |  30 |   2
   40001 |  40 |   1
(11 rows)
```

有关 WINSALES 表的说明，请参阅[窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

以下示例按 SELLERID 对表进行分区，按数量对每个分区进行排序（按降序顺序），并为每个行分配排名。在应用窗口函数结果后，对结果进行排序。

```
select salesid, sellerid, qty, rank() over
(partition by sellerid
order by qty desc) as rank
from winsales
order by 2,3,1;

salesid | sellerid | qty | rank
--------+----------+-----+-----
  10001 |        1 |  10 |  2
  10006 |        1 |  10 |  2
  10005 |        1 |  30 |  1
  20001 |        2 |  20 |  1
  20002 |        2 |  20 |  1
  30001 |        3 |  10 |  4
  30003 |        3 |  15 |  3
  30004 |        3 |  20 |  2
  30007 |        3 |  30 |  1
  40005 |        4 |  10 |  2
  40001 |        4 |  40 |  1
(11 rows)
```

# RATIO\$1TO\$1REPORT 开窗函数
<a name="r_WF_RATIO_TO_REPORT"></a>

计算某个窗口或分区中的某个值与所有值的和的比率。使用以下公式确定报表值的比率：

`value of `*ratio\$1expression* `argument for the current row / sum of` *ratio\$1expression* `argument for the window or partition`

以下数据集说明了此公式的使用：

```
Row#	Value	Calculation	RATIO_TO_REPORT
1	2500	(2500)/(13900)	0.1798
2	2600	(2600)/(13900)	0.1870
3	2800	(2800)/(13900)	0.2014
4	2900	(2900)/(13900)	0.2086
5	3100	(3100)/(13900)	0.2230
```

返回值范围介于 0 和 1（含 1）之间。如果 *ratio\$1expression* 为 NULL，则返回值为 `NULL`。如果 *partition\$1expression* 中的值是唯一的，则函数将为该值返回 `1`。

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

```
RATIO_TO_REPORT ( ratio_expression )
OVER ( [ PARTITION BY partition_expression ] )
```

## 参数
<a name="r_WF_RATIO_TO_REPORT-arguments"></a>

*ratio\$1expression*   
一个提供要为其确定比率的值的表达式（例如列名）。该表达式必须具有数字数据类型或可隐式转换为 1。  
您无法在 *ratio\$1expression* 中使用任何其他分析函数。

OVER  
一个指定窗口分区的子句。OVER 子句不能包含窗口排序或窗口框架规范。

PARTITION BY *partition\$1expression*   
可选。一个设置 OVER 子句中每个组的记录范围的表达式。

## 返回类型
<a name="r_WF_RATIO_TO_REPORT-return-type"></a>

FLOAT8

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

以下各示例使用 WINSALES 表。有关如何创建 WINSALES 表的信息，请参阅[窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

以下示例计算每行卖家数量占所有卖家总数量的比率值。

```
select sellerid, qty, ratio_to_report(qty) 
over()
from winsales
order by sellerid;

sellerid  qty    ratio_to_report
--------------------------------------
1         30     0.13953488372093023	
1         10     0.046511627906976744	
1         10     0.046511627906976744	
2         20     0.09302325581395349	
2         20     0.09302325581395349	
3         30     0.13953488372093023	
3         20     0.09302325581395349	
3         15     0.06976744186046512	
3         10     0.046511627906976744	
4         10     0.046511627906976744	
4         40     0.18604651162790697
```

以下示例按分区计算每个卖家的销售数量的比率。

```
select sellerid, qty, ratio_to_report(qty) 
over(partition by sellerid) 
from winsales;

sellerid   qty    ratio_to_report
-------------------------------------------
2          20     0.5	
2          20     0.5	
4          40     0.8	
4          10     0.2	
1          10     0.2	
1          30     0.6	
1          10     0.2	
3          10     0.13333333333333333	
3          15     0.2	
3          20     0.26666666666666666	
3          30     0.4
```

# ROW\$1NUMBER 窗口函数
<a name="r_WF_ROW_NUMBER"></a>

根据 OVER 子句中的 ORDER BY 表达式，分配一组行中当前行的序号（从 1 开始计数）。如果存在可选的 PARTITION BY 子句，则为每组行重置序号。ORDER BY 表达式中具有相同值的行以非确定性的方式接收不同的行号。

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

```
ROW_NUMBER() OVER(
  [ PARTITION BY expr_list ]
  [ ORDER BY order_list ]
)
```

## 参数
<a name="r_WF_ROW_NUMBER-arguments"></a>

( )   
该函数没有参数，但需要空括号。

OVER   
适用于 ROW\$1NUMBER 函数的窗口函数子句。

PARTITION BY *expr\$1list*   
可选。一个或多个将结果划分成行集的列表达式。

ORDER BY *order\$1list*   
可选。一个或多个定义集合内的行顺序的列表达式。如果未指定 PARTITION BY，则 ORDER BY 使用整个表。  
如果 ORDER BY 未生成唯一顺序或被省略，则行的顺序是不确定的。有关更多信息，请参阅 [窗口函数的唯一数据排序](c_Window_functions.md#r_Examples_order_by_WF)。

## 返回类型
<a name="c_Supported_data_types_r_WF_ROW_NUMBER"></a>

BIGINT

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

下面的示例使用 `WINSALES` 表。有关 `WINSALES` 表的说明，请参阅[窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

以下示例按 QTY 对表进行排序（按升序），然后为每个行分配一个行号。在应用窗口函数结果后，对结果进行排序。

```
SELECT salesid, sellerid, qty, 
ROW_NUMBER() OVER(
   ORDER BY qty ASC) AS row
FROM winsales
ORDER BY 4,1;

salesid   sellerid   qty   row
---------+----------+-----+-----
   30001 |        3 |  10 |   1	
   10001 |        1 |  10 |   2	
   10006 |        1 |  10 |   3
   40005 |        4 |  10 |   4
   30003 |        3 |  15 |   5
   20001 |        2 |  20 |   6
   20002 |        2 |  20 |   7
   30004 |        3 |  20 |   8
   10005 |        1 |  30 |   9
   30007 |        3 |  30 |  10
   40001 |        4 |  40 |  11
```

以下示例按 SELLERID 对表进行分区并按 QTY 对每个分区进行排序（按升序顺序），然后为每个行分配一个行号。在应用窗口函数结果后，对结果进行排序。

```
SELECT salesid, sellerid, qty, 
ROW_NUMBER() OVER(
  PARTITION BY sellerid
  ORDER BY qty ASC) AS row_by_seller
FROM winsales
ORDER BY 2,4;

 salesid | sellerid | qty | row_by_seller
---------+----------+-----+-----
   10001 |        1 |  10 |   1
   10006 |        1 |  10 |   2
   10005 |        1 |  30 |   3
   20001 |        2 |  20 |   1
   20002 |        2 |  20 |   2
   30001 |        3 |  10 |   1
   30003 |        3 |  15 |   2
   30004 |        3 |  20 |   3
   30007 |        3 |  30 |   4
   40005 |        4 |  10 |   1
   40001 |        4 |  40 |   2
```

以下示例显示了不使用可选子句时的结果。

```
SELECT salesid, sellerid, qty, ROW_NUMBER() OVER() AS row
FROM winsales
ORDER BY 4,1;

salesid   sellerid   qty   row
---------+----------+-----+-----
   30001 |        3 |  10 |   1	
   10001 |        1 |  10 |   2	
   10005 |        1 |  30 |   3
   40001 |        4 |  40 |   4
   10006 |        1 |  10 |   5
   20001 |        2 |  20 |   6
   40005 |        4 |  10 |   7
   20002 |        2 |  20 |   8
   30003 |        3 |  15 |   9
   30004 |        3 |  20 |  10
   30007 |        3 |  30 |  11
```

# STDDEV\$1SAMP 和 STDDEV\$1POP 窗口函数
<a name="r_WF_STDDEV"></a>

STDDEV\$1SAMP 和 STDDEV\$1POP 窗口函数返回一组数值（整数、小数或浮点）的样本标准差和总体标准差。另请参阅 [STDDEV\$1SAMP 和 STDDEV\$1POP 函数](r_STDDEV_functions.md)。

STDDEV\$1SAMP 和 STDDEV 是同一函数的同义词。

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

```
STDDEV_SAMP | STDDEV | STDDEV_POP
( [ ALL ] expression ) OVER
(
[ PARTITION BY expr_list ]
[ ORDER BY order_list 
                        frame_clause ]
)
```

## 参数
<a name="r_WF_STDDEV-arguments"></a>

 *expression*   
对其执行函数的目标列或表达式。

ALL   
利用参数 ALL，该函数可保留表达式中的所有重复值。ALL 是默认值。DISTINCT 不受支持。

OVER   
指定聚合函数的窗口子句。OVER 子句将窗口聚合函数与普通集合聚合函数区分开来。

PARTITION BY *expr\$1list*   
依据一个或多个表达式定义函数的窗口。

ORDER BY *order\$1list*   
对每个分区中的行进行排序。如果未指定 PARTITION BY，则 ORDER BY 使用整个表。

 *frame\$1clause*   
如果 ORDER BY 子句用于聚合函数，则需要显式框架子句。框架子句优化函数窗口中的行集，包含或排除已排序结果中的行集。框架子句包括 ROWS 关键字和关联的说明符。请参阅 [窗口函数语法摘要](c_Window_functions.md#r_Window_function_synopsis)。

## 数据类型
<a name="c_Supported_data_types_wf_stddev"></a>

STDDEV 函数支持的参数类型包括 SMALLINT、INTEGER、BIGINT、NUMERIC、DECIMAL、REAL 和 DOUBLE PRECISION。

无论表达式的数据类型如何，STDDEV 函数的返回类型都是双精度数。

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

以下示例说明如何使用 STDDEV\$1POP 和 VAR\$1POP 作为窗口函数。查询计算 SALES 表中 PRICEPAID 值的总体方差和总体标准差。

```
select salesid, dateid, pricepaid,
round(stddev_pop(pricepaid) over
(order by dateid, salesid rows unbounded preceding)) as stddevpop,
round(var_pop(pricepaid) over
(order by dateid, salesid rows unbounded preceding)) as varpop
from sales
order by 2,1;

salesid | dateid | pricepaid | stddevpop | varpop
--------+--------+-----------+-----------+---------
  33095 |   1827 |    234.00 |         0 |       0
  65082 |   1827 |    472.00 |       119 |   14161
  88268 |   1827 |    836.00 |       248 |   61283
  97197 |   1827 |    708.00 |       230 |   53019
 110328 |   1827 |    347.00 |       223 |   49845
 110917 |   1827 |    337.00 |       215 |   46159
 150314 |   1827 |    688.00 |       211 |   44414
 157751 |   1827 |   1730.00 |       447 |  199679
 165890 |   1827 |   4192.00 |      1185 | 1403323
...
```

样本标准差和样本标准方差函数可通过同一方式使用。

# SUM 窗口函数
<a name="r_WF_SUM"></a>

 SUM 窗口函数返回输入列值或表达式值的和。SUM 函数使用数值并忽略 NULL 值。

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

```
SUM ( [ ALL ] expression ) OVER
(
[ PARTITION BY expr_list ]
[ ORDER BY order_list 
                        frame_clause ]
)
```

## 参数
<a name="r_WF_SUM-arguments"></a>

 *expression*   
对其执行函数的目标列或表达式。

ALL   
利用参数 ALL，该函数可保留表达式中的所有重复值。ALL 是默认值。DISTINCT 不受支持。

OVER   
指定聚合函数的窗口子句。OVER 子句将窗口聚合函数与普通集合聚合函数区分开来。

PARTITION BY *expr\$1list*   
依据一个或多个表达式定义 SUM 函数的窗口。

ORDER BY *order\$1list*   
对每个分区中的行进行排序。如果未指定 PARTITION BY，则 ORDER BY 使用整个表。

 *frame\$1clause*   
如果 ORDER BY 子句用于聚合函数，则需要显式框架子句。框架子句优化函数窗口中的行集，包含或排除已排序结果中的行集。框架子句包括 ROWS 关键字和关联的说明符。请参阅 [窗口函数语法摘要](c_Window_functions.md#r_Window_function_synopsis)。

## 数据类型
<a name="c_Supported_data_types_wf_sum"></a>

SUM 函数支持的参数类型为 SMALLINT、INTEGER、BIGINT、NUMERIC、DECIMAL、REAL 和 DOUBLE PRECISION。

SUM 函数支持的返回类型为：
+ 适用于 SMALLINT 或 INTEGER 参数的 BIGINT
+ 适用于 BIGINT 参数的 NUMERIC
+ 适用于浮点参数的 DOUBLE PRECISION

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

以下示例创建按日期和销售 ID 排序的销售数量的累积（移动）和：

```
select salesid, dateid, sellerid, qty,
sum(qty) over (order by dateid, salesid rows unbounded preceding) as sum
from winsales
order by 2,1;

salesid |   dateid   | sellerid | qty | sum
---------+------------+----------+-----+-----
30001 | 2003-08-02 |        3 |  10 |  10
10001 | 2003-12-24 |        1 |  10 |  20
10005 | 2003-12-24 |        1 |  30 |  50
40001 | 2004-01-09 |        4 |  40 |  90
10006 | 2004-01-18 |        1 |  10 | 100
20001 | 2004-02-12 |        2 |  20 | 120
40005 | 2004-02-12 |        4 |  10 | 130
20002 | 2004-02-16 |        2 |  20 | 150
30003 | 2004-04-18 |        3 |  15 | 165
30004 | 2004-04-18 |        3 |  20 | 185
30007 | 2004-09-07 |        3 |  30 | 215
(11 rows)
```

 有关 WINSALES 表的说明，请参阅[窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

以下示例按日期创建销售数量的累积（移动）和，按卖家 ID 对结果进行分区，并按日期和销售 ID 对该分区中的结果进行排序：

```
select salesid, dateid, sellerid, qty,
sum(qty) over (partition by sellerid
order by dateid, salesid rows unbounded preceding) as sum
from winsales
order by 2,1;

salesid |   dateid   | sellerid | qty | sum
---------+------------+----------+-----+-----
30001 | 2003-08-02 |        3 |  10 |  10
10001 | 2003-12-24 |        1 |  10 |  10
10005 | 2003-12-24 |        1 |  30 |  40
40001 | 2004-01-09 |        4 |  40 |  40
10006 | 2004-01-18 |        1 |  10 |  50
20001 | 2004-02-12 |        2 |  20 |  20
40005 | 2004-02-12 |        4 |  10 |  50
20002 | 2004-02-16 |        2 |  20 |  40
30003 | 2004-04-18 |        3 |  15 |  25
30004 | 2004-04-18 |        3 |  20 |  45
30007 | 2004-09-07 |        3 |  30 |  75
(11 rows)
```

对结果集中的所有行进行编号（按 SELLERID 和 SALESID 列进行排序）：

```
select salesid, sellerid, qty,
sum(1) over (order by sellerid, salesid rows unbounded preceding) as rownum
from winsales
order by 2,1;

salesid | sellerid |  qty | rownum
--------+----------+------+--------
10001 |        1 |   10 |     1
10005 |        1 |   30 |     2
10006 |        1 |   10 |     3
20001 |        2 |   20 |     4
20002 |        2 |   20 |     5
30001 |        3 |   10 |     6
30003 |        3 |   15 |     7
30004 |        3 |   20 |     8
30007 |        3 |   30 |     9
40001 |        4 |   40 |    10
40005 |        4 |   10 |    11
(11 rows)
```

有关 WINSALES 表的说明，请参阅[窗口函数示例的示例表](c_Window_functions.md#r_Window_function_example)。

以下示例对结果集中的所有行按顺序进行编号，按 SELLERID 对结果进行分区，并按 SELLERID 和 SALESID 对该分区中的结果进行排序：

```
select salesid, sellerid, qty,
sum(1) over (partition by sellerid
order by sellerid, salesid rows unbounded preceding) as rownum
from winsales
order by 2,1;

salesid | sellerid | qty | rownum
---------+----------+-----+--------
10001 |        1 |  10 |      1
10005 |        1 |  30 |      2
10006 |        1 |  10 |      3
20001 |        2 |  20 |      1
20002 |        2 |  20 |      2
30001 |        3 |  10 |      1
30003 |        3 |  15 |      2
30004 |        3 |  20 |      3
30007 |        3 |  30 |      4
40001 |        4 |  40 |      1
40005 |        4 |  10 |      2
(11 rows)
```

# VAR\$1SAMP 和 VAR\$1POP 窗口函数
<a name="r_WF_VARIANCE"></a>

 VAR\$1SAMP 和 VAR\$1POP 窗口函数返回一组数值（整数、小数或浮点）的样本方差和总体方差。另请参阅 [VAR\$1SAMP 和 VAR\$1POP 函数](r_VARIANCE_functions.md)。

VAR\$1SAMP 和 VARIANCE 是同一函数的同义词。

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

```
VAR_SAMP | VARIANCE | VAR_POP
( [ ALL ] expression ) OVER
(
[ PARTITION BY expr_list ]
[ ORDER BY order_list 
                        frame_clause ]
)
```

## 参数
<a name="r_WF_VARIANCE-arguments"></a>

 *expression*   
对其执行函数的目标列或表达式。

ALL   
利用参数 ALL，该函数可保留表达式中的所有重复值。ALL 是默认值。DISTINCT 不受支持。

OVER   
指定聚合函数的窗口子句。OVER 子句将窗口聚合函数与普通集合聚合函数区分开来。

PARTITION BY *expr\$1list*   
依据一个或多个表达式定义函数的窗口。

ORDER BY *order\$1list*   
对每个分区中的行进行排序。如果未指定 PARTITION BY，则 ORDER BY 使用整个表。

 *frame\$1clause*   
如果 ORDER BY 子句用于聚合函数，则需要显式框架子句。框架子句优化函数窗口中的行集，包含或排除已排序结果中的行集。框架子句包括 ROWS 关键字和关联的说明符。请参阅 [窗口函数语法摘要](c_Window_functions.md#r_Window_function_synopsis)。

## 数据类型
<a name="c_Supported_data_types_wf_variance"></a>

VARIANCE 函数支持的参数类型包括 SMALLINT、INTEGER、BIGINT、NUMERIC、DECIMAL、REAL 和 DOUBLE PRECISION。

无论表达式的数据类型如何，VARIANCE 函数的返回类型都是双精度数。

# 系统管理函数
<a name="r_System_administration_functions"></a>

**Topics**
+ [CHANGE\$1QUERY\$1PRIORITY](r_CHANGE_QUERY_PRIORITY.md)
+ [CHANGE\$1SESSION\$1PRIORITY](r_CHANGE_SESSION_PRIORITY.md)
+ [CHANGE\$1USER\$1PRIORITY](r_CHANGE_USER_PRIORITY.md)
+ [CURRENT\$1SETTING](r_CURRENT_SETTING.md)
+ [PG\$1CANCEL\$1BACKEND](PG_CANCEL_BACKEND.md)
+ [PG\$1TERMINATE\$1BACKEND](PG_TERMINATE_BACKEND.md)
+ [REBOOT\$1CLUSTER](r_REBOOT_CLUSTER.md)
+ [SET\$1CONFIG](r_SET_CONFIG.md)

Amazon Redshift 支持若干系统管理函数。

# CHANGE\$1QUERY\$1PRIORITY
<a name="r_CHANGE_QUERY_PRIORITY"></a>

CHANGE\$1QUERY\$1PRIORITY 使超级用户能够修改在工作负载管理 (WLM) 中运行或等待的查询的优先级。

此功能使超级用户可以立即更改系统中任何查询的优先级。只有一个查询、用户或会话可以使用优先级 `CRITICAL` 运行。

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

```
CHANGE_QUERY_PRIORITY(query_id, priority)
```

## 参数
<a name="r_CHANGE_QUERY_PRIORITY-argument"></a>

 *query\$1id*   
更改其优先级的查询的查询标识符。需要 `INTEGER` 值。

 *priority*   
要分配给查询的新优先级。此参数必须是包含以下值的字符串：`CRITICAL`、`HIGHEST`、`HIGH`、`NORMAL`、`LOW` 或 `LOWEST`。

## 返回类型
<a name="r_CHANGE_QUERY_PRIORITY-return-type"></a>

无

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

要显示 STV\$1WLM\$1QUERY\$1STATE 系统表中的列 `query_priority`，请使用以下示例。

```
SELECT query, service_class, query_priority, state 
FROM stv_wlm_query_state WHERE service_class = 101;

+-------+---------------+----------------+---------+
| query | service_class | query_priority |  state  |
+-------+---------------+----------------+---------+
|  1076 |           101 | Lowest         | Running |
|  1075 |           101 | Lowest         | Running |
+-------+---------------+----------------+---------+
```

要显示运行函数 `change_query_priority` 以将优先级更改为 `CRITICAL` 的超级用户的结果，请使用以下示例。

```
SELECT CHANGE_QUERY_PRIORITY(1076, 'Critical');
            
+-------------------------------------------------------------------------------+
|                             change_query_priority                             |
+-------------------------------------------------------------------------------+
| Succeeded to change query priority. Priority changed from Lowest to Critical. |
+-------------------------------------------------------------------------------+
```

# CHANGE\$1SESSION\$1PRIORITY
<a name="r_CHANGE_SESSION_PRIORITY"></a>

CHANGE\$1SESSION\$1PRIORITY 使超级用户可以立即更改系统中任何会话的优先级。只有一个会话、用户或查询可以使用优先级 `CRITICAL` 运行。

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

```
CHANGE_SESSION_PRIORITY(pid, priority)
```

## 参数
<a name="r_CHANGE_SESSION_PRIORITY-argument"></a>

 *pid*   
更改其优先级的会话的进程标识符。值 `-1` 指的是当前会话。需要 `INTEGER` 值。

 *priority*   
要分配给会话的新优先级。此参数必须是包含以下值的字符串：`CRITICAL`、`HIGHEST`、`HIGH`、`NORMAL`、`LOW` 或 `LOWEST`。

## 返回类型
<a name="r_CHANGE_SESSION_PRIORITY-return-type"></a>

无

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

要返回处理当前会话的服务器进程的进程标识符，请使用以下示例。

```
SELECT pg_backend_pid();
               
+----------------+
| pg_backend_pid |
+----------------+
|          30311 |
+----------------+
```

在此示例中，将当前会话的优先级更改为 `LOWEST`。

```
SELECT CHANGE_SESSION_PRIORITY(30311, 'Lowest');
               
+---------------------------------------------------------------------------------------+
|                                change_session_priority                                |
+---------------------------------------------------------------------------------------+
| Succeeded to change session priority. Changed session (pid:30311) priority to lowest. |
+---------------------------------------------------------------------------------------+
```

在此示例中，将当前会话的优先级更改为 `HIGH`。

```
SELECT CHANGE_SESSION_PRIORITY(-1, 'High');

+-------------------------------------------------------------------------------------------------+
|                                     change_session_priority                                     |
+-------------------------------------------------------------------------------------------------+
| Succeeded to change session priority. Changed session (pid:30311) priority from lowest to high. |
+-------------------------------------------------------------------------------------------------+
```

要创建用于更改会话优先级的存储过程，请使用以下示例。运行此存储过程的权限授予数据库用户 `test_user`。

```
CREATE OR REPLACE PROCEDURE sp_priority_low(pid IN int, result OUT varchar)
AS $$
BEGIN
  SELECT CHANGE_SESSION_PRIORITY(pid, 'low') into result;
END;
$$ LANGUAGE plpgsql
SECURITY DEFINER;
GRANT EXECUTE ON PROCEDURE sp_priority_low(int) TO test_user;
```

然后，名为 `test_user` 的数据库用户调用该过程。

```
CALL sp_priority_low(pg_backend_pid()); 

+------------------------------------------------------+
|                        result                        |
+------------------------------------------------------+
| Success. Change session (pid:13155) priority to low. |
+------------------------------------------------------+
```

# CHANGE\$1USER\$1PRIORITY
<a name="r_CHANGE_USER_PRIORITY"></a>

CHANGE\$1USER\$1PRIORITY 使超级用户能够修改由在工作负载管理 (WLM) 中运行或等待的用户发出的所有查询的优先级。只有一个用户、会话或查询可以使用优先级 `CRITICAL` 运行。

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

```
CHANGE_USER_PRIORITY(user_name, priority)
```

## 参数
<a name="r_CHANGE_USER_PRIORITY-argument"></a>

 *user\$1name*   
查询优先级已更改的数据库用户名。

 *priority*   
`user_name` 要分配给所有查询的新优先级。此参数必须是包含以下值的字符串：`CRITICAL`、`HIGHEST`、`HIGH`、`NORMAL`、`LOW`、`LOWEST` 或 `RESET`。只有超级用户才能将优先级更改为 `CRITICAL`。将优先级更改为 `RESET` 会删除 `user_name` 的优先级设置。

## 返回类型
<a name="r_CHANGE_USER_PRIORITY-return-type"></a>

无

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

要将用户 `analysis_user` 的优先级更改为 `LOWEST`，请使用以下示例。

```
SELECT CHANGE_USER_PRIORITY('analysis_user', 'lowest');

+-------------------------------------------------------------------------------------+
|                                change_user_priority                                 |
+-------------------------------------------------------------------------------------+
| Succeeded to change user priority. Changed user (analysis_user) priority to lowest. |
+-------------------------------------------------------------------------------------+
```

要将优先级更改为 `LOW`，请使用以下示例。

```
SELECT CHANGE_USER_PRIORITY('analysis_user', 'low');

+----------------------------------------------------------------------------------------------+
|                                     change_user_priority                                     |
+----------------------------------------------------------------------------------------------+
| Succeeded to change user priority. Changed user (analysis_user) priority from Lowest to low. |
+----------------------------------------------------------------------------------------------+
```

要重置优先级，请使用以下示例。

```
SELECT CHANGE_USER_PRIORITY('analysis_user', 'reset');

+-------------------------------------------------------+
|                 change_user_priority                  |
+-------------------------------------------------------+
| Succeeded to reset priority for user (analysis_user). |
+-------------------------------------------------------+
```

# CURRENT\$1SETTING
<a name="r_CURRENT_SETTING"></a>

 CURRENT\$1SETTING 返回指定配置参数的当前值。

此函数等效于 [SHOW](r_SHOW.md) 命令。

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

```
current_setting('parameter')
```

以下语句返回指定会话上下文变量的当前值。

```
current_setting('variable_name')
current_setting('variable_name'[, error_if_undefined])
```

## 参数
<a name="r_CURRENT_SETTING-argument"></a>

 *parameter*   
要显示的参数值。有关配置参数的列表，请参阅[配置参考](cm_chap_ConfigurationRef.md)

 *variable\$1name *   
要显示的变量的名称。对于会话上下文变量，它必须是字符串常量。

 *error\$1if\$1undefined*   
（可选）一个布尔值，该值指定变量名不存在时的行为。当 error\$1if\$1undefined 设置为 `TRUE`（默认值）时，Amazon Redshift 会引发错误。当 error\$1if\$1undefined 设置为 `FALSE` 时，Amazon Redshift 会返回 `NULL`。Amazon Redshift 仅支持将 *error\$1if\$1undefined* 参数用于会话上下文变量。当输入为配置参数时，不能使用此项。

## 返回类型
<a name="r_CURRENT_SETTING-return-type"></a>

返回 `CHAR` 或 `VARCHAR` 字符串。

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

要返回 `query_group` 参数的当前设置，请使用以下示例。

```
SELECT CURRENT_SETTING('query_group');

+-----------------+
| current_setting |
+-----------------+
| unset           |
+-----------------+
```

要返回变量 `app_context.user_id` 的当前设置，请使用以下示例。

```
SELECT CURRENT_SETTING('app_context.user_id', FALSE);
```

# PG\$1CANCEL\$1BACKEND
<a name="PG_CANCEL_BACKEND"></a>

取消查询。PG\$1CANCEL\$1BACKEND 的功能等效于 [CANCEL](r_CANCEL.md) 命令。您可取消当前由您的用户运行的查询。超级用户可取消任何查询。

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

```
pg_cancel_backend( pid )
```

## 参数
<a name="PG_CANCEL_BACKEND-arguments"></a>

 *pid*   
要取消的查询的进程 ID (PID)。您不能通过指定查询 ID 来取消查询；您必须指定查询的进程 ID。需要 `INTEGER` 值。

## 返回类型
<a name="PG_CANCEL_BACKEND-return-type"></a>

无

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

如果多个会话中的查询在同一个表上保持锁定状态，您可以使用 [PG\$1TERMINATE\$1BACKEND](PG_TERMINATE_BACKEND.md) 函数终止其中一个会话，这将强制所终止会话中所有当前运行的事务释放锁定并回滚事务。查询 PG\$1\$1LOCKS 目录表以查看当前持有的锁。如果某个查询由于位于事务块 (BEGIN … END) 中而无法取消，您可使用 PG\$1TERMINATE\$1BACKEND 函数终止在其中运行该查询的会话。

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

要取消当前正在运行的查询，请先检索要取消的查询的进程 ID。要确定所有当前正在运行的查询的进程 ID，请运行以下命令。

```
SELECT pid, TRIM(starttime) AS start, 
duration, TRIM(user_name) AS user,
SUBSTRING(query,1,40) AS querytxt
FROM stv_recents
WHERE status = 'Running';

+-----+------------------------+----------+--------+-----------------------------+
| pid |       starttime        | duration |  user  |          querytxt           |
+-----+------------------------+----------+--------+-----------------------------+
| 802 | 2013-10-14 09:19:03.55 |      132 | dwuser | select venuename from venue |
| 834 | 2013-10-14 08:33:49.47 |  1250414 | dwuser | select * from listing;      |
| 964 | 2013-10-14 08:30:43.29 |   326179 | dwuser | select sellerid from sales  |
+-----+------------------------+----------+--------+-----------------------------+
```

要取消进程 ID 为 802 的查询，请使用以下示例。

```
SELECT PG_CANCEL_BACKEND(802);
```

# PG\$1TERMINATE\$1BACKEND
<a name="PG_TERMINATE_BACKEND"></a>

终止会话。您可终止您的用户拥有的会话。超级用户可终止任何会话。

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

```
pg_terminate_backend( pid )
```

## 参数
<a name="PG_TERMINATE_BACKEND-arguments"></a>

*pid*  
要终止的会话的进程 ID。需要 `INTEGER` 值。

## 返回类型
<a name="PG_TERMINATE_BACKEND-return-type"></a>

无

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

 如果您即将达到并行连接的限制，请使用 PG\$1TERMINATE\$1BACKEND 终止空闲会话并释放连接。有关更多信息，请参阅 [Amazon Redshift 限制](https://docs.aws.amazon.com/redshift/latest/mgmt/amazon-redshift-limits.html)。

如果多个会话中的查询锁定到了同一个表，您可以使用 PG\$1TERMINATE\$1BACKEND 终止其中一个会话，这将强制已终止会话中所有当前运行的事务释放锁定并回滚事务。查询 PG\$1LOCKS 目录表以查看当前持有的锁。

如果某个查询不在事务块 (BEGIN … END) 中，您可使用 [CANCEL](r_CANCEL.md) 命令或 [PG\$1CANCEL\$1BACKEND](PG_CANCEL_BACKEND.md) 函数取消该查询。

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

要查询 SVV\$1TRANSACTIONS 表以查看对当前事务生效的所有锁，请使用以下示例。

```
SELECT * FROM svv_transactions;

+-----------+--------+-------+------+---------------------+-----------------+----------------------+----------+---------+
| txn_owner | txn_db |  xid  | pid  |      txn_start      |    lock_mode    | lockable_object_type | relation | granted |
+-----------+--------+-------+------+---------------------+-----------------+----------------------+----------+---------+
| rsuser    | dev    | 96178 | 8585 | 2017-04-12 20:13:07 | AccessShareLock | relation             |    51940 | true    |
| rsuser    | dev    | 96178 | 8585 | 2017-04-12 20:13:07 | AccessShareLock | relation             |    52000 | true    |
| rsuser    | dev    | 96178 | 8585 | 2017-04-12 20:13:07 | AccessShareLock | relation             |   108623 | true    |
| rsuser    | dev    | 96178 | 8585 | 2017-04-12 20:13:07 | ExclusiveLock   | transactionid        |          | true    |
+-----------+--------+-------+------+---------------------+-----------------+----------------------+----------+---------+
```

要终止持有锁的会话，请使用以下示例。

```
SELECT PG_TERMINATE_BACKEND(8585); 
```

# REBOOT\$1CLUSTER
<a name="r_REBOOT_CLUSTER"></a>

在不关闭与集群的连接的情况下，重新启动 Amazon Redshift 集群。您必须是数据库超级用户才能执行此命令。

软重启完成后，Amazon Redshift 集群会向用户应用程序返回一个错误，并要求用户应用程序重新提交因软重启而中断的任何事务或查询。

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

```
SELECT REBOOT_CLUSTER();
```

# SET\$1CONFIG
<a name="r_SET_CONFIG"></a>

将配置参数设为新的设置。

 此函数等效于 SQL 中的 SET 命令。

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

```
SET_CONFIG('parameter', 'new_value' , is_local)
```

以下语句将会话上下文变量设置为新设置。

```
set_config('variable_name', 'new_value' , is_local)
```

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

 *parameter*   
要设置的参数。

 *variable\$1name*   
要设置的变量的名称。

 *new\$1value*   
参数的新值。

 *is\$1local*   
如果为 true，则参数值仅适用于当前事务。有效值为 `true` 或 `1` 以及 `false` 或 `0`。

## 返回类型
<a name="r_SET_CONFIG-return-type"></a>

返回 `CHAR` 或 `VARCHAR` 字符串。

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

要仅针对当前事务将 `query_group` 参数的值设置为 `test`，请使用以下示例。

```
SELECT SET_CONFIG('query_group', 'test', true);

+------------+
| set_config |
+------------+
| test       |
+------------+
```

要设置会话上下文变量，请使用以下示例。

```
SELECT SET_CONFIG(‘app.username’, ‘cuddy’, FALSE);
```

# 系统信息函数
<a name="r_System_information_functions"></a>

Amazon Redshift 支持很多系统信息函数。

**Topics**
+ [CURRENT\$1AWS\$1ACCOUNT](r_CURRENT_AWS_ACCOUNT.md)
+ [CURRENT\$1DATABASE](r_CURRENT_DATABASE.md)
+ [CURRENT\$1NAMESPACE](r_CURRENT_NAMESPACE.md)
+ [CURRENT\$1SCHEMA](r_CURRENT_SCHEMA.md)
+ [CURRENT\$1SCHEMAS](r_CURRENT_SCHEMAS.md)
+ [CURRENT\$1SESSION\$1ARN](r_CURRENT_SESSION_ARN.md)
+ [CURRENT\$1USER](r_CURRENT_USER.md)
+ [CURRENT\$1USER\$1ID](r_CURRENT_USER_ID.md)
+ [DEFAULT\$1IAM\$1ROLE](r_DEFAULT_IAM_ROLE.md)
+ [GET\$1MOUNTED\$1ROLE](GET_MOUNTED_ROLE.md)
+ [HAS\$1ASSUMEROLE\$1PRIVILEGE](r_HAS_ASSUMEROLE_PRIVILEGE.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)
+ [LAST\$1USER\$1QUERY\$1ID](LAST_USER_QUERY_ID.md)
+ [PG\$1BACKEND\$1PID](PG_BACKEND_PID.md)
+ [PG\$1GET\$1COLS](PG_GET_COLS.md)
+ [PG\$1GET\$1GRANTEE\$1BY\$1IAM\$1ROLE](PG_GET_GRANTEE_BY_IAMROLE.md)
+ [PG\$1GET\$1IAM\$1ROLE\$1BY\$1USER](PG_GET_IAM_ROLE_BY_USER.md)
+ [PG\$1GET\$1LATE\$1BINDING\$1VIEW\$1COLS](PG_GET_LATE_BINDING_VIEW_COLS.md)
+ [PG\$1GET\$1SESSION\$1ROLES](PG_GET_SESSION_ROLES.md)
+ [PG\$1LAST\$1COPY\$1COUNT](PG_LAST_COPY_COUNT.md)
+ [PG\$1LAST\$1COPY\$1ID](PG_LAST_COPY_ID.md)
+ [PG\$1LAST\$1UNLOAD\$1ID](PG_LAST_UNLOAD_ID.md)
+ [PG\$1LAST\$1QUERY\$1ID](PG_LAST_QUERY_ID.md)
+ [PG\$1LAST\$1UNLOAD\$1COUNT](PG_LAST_UNLOAD_COUNT.md)
+ [SLICE\$1NUM 函数](r_SLICE_NUM.md)
+ [USER](r_USER.md)
+ [ROLE\$1IS\$1MEMBER\$1OF](r_ROLE_IS_MEMBER_OF.md)
+ [USER\$1IS\$1MEMBER\$1OF](r_USER_IS_MEMBER_OF.md)
+ [VERSION](r_VERSION.md)

# CURRENT\$1AWS\$1ACCOUNT
<a name="r_CURRENT_AWS_ACCOUNT"></a>

返回与提交查询的 Amazon Redshift 集群关联的 AWS 账户。

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

```
current_aws_account
```

## 返回类型
<a name="r_CURRENT_AWS_ACCOUNT-return-type"></a>

返回整数。

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

以下查询返回当前数据库的名称。

```
select user, current_aws_account; 
current_user | current_account
-------------+--------------- 
dwuser       | 987654321

(1 row)
```

# CURRENT\$1DATABASE
<a name="r_CURRENT_DATABASE"></a>

返回您当前连接到的数据库的名称。

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

```
current_database()
```

## 返回类型
<a name="r_CURRENT_DATABASE-return-type"></a>

返回 CHAR 或 VARCHAR 字符串。

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

以下查询返回当前数据库的名称。

```
select current_database();

current_database
------------------
tickit
(1 row)
```

# CURRENT\$1NAMESPACE
<a name="r_CURRENT_NAMESPACE"></a>

返回当前 Amazon Redshift 集群的集群命名空间。Amazon Redshift 集群命名空间是 Amazon Redshift 集群的唯一 ID。

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

```
current_namespace
```

## 返回类型
<a name="r_CURRENT_NAMESPACE-return-type"></a>

返回 CHAR 或 VARCHAR 字符串。

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

以下查询返回当前命名空间的名称。

```
select user, current_namespace; 
current_user | current_namespace
-------------+-------------------------------------
dwuser       | 86b5169f-01dc-4a6f-9fbb-e2e24359e9a8

(1 row)
```

# CURRENT\$1SCHEMA
<a name="r_CURRENT_SCHEMA"></a>

返回位于搜索路径前部的 schema 的名称。此 schema 将用于在创建时未指定目标 schema 的任何表或其他命名对象。

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

**注意**  
这是领导节点函数。如果此函数引用了用户创建的表、STL/STV 系统表或 SVV/SVL 系统视图，它将返回错误。

```
current_schema()
```

## 返回类型
<a name="r_CURRENT_SCHEMA-return-type"></a>

CURRENT\$1SCHEMA 返回 CHAR 或 VARCHAR 字符串。

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

以下查询将返回当前 schema：

```
select current_schema();

current_schema
----------------
public
(1 row)
```

# CURRENT\$1SCHEMAS
<a name="r_CURRENT_SCHEMAS"></a>

返回当前搜索路径中任何 schemas 的名称的数组。当前搜索路径是在 search\$1path 参数中定义的。

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

**注意**  
这是领导节点函数。如果此函数引用了用户创建的表、STL/STV 系统表或 SVV/SVL 系统视图，它将返回错误。

```
current_schemas(include_implicit)
```

## 参数
<a name="r_CURRENT_SCHEMAS-argument"></a>

 *include\$1implicit*   
如果为 True，则指定搜索路径应包含任何隐式包含的系统 schemas。有效值为 `true` 和 `false`。通常，如果为 `true`，此参数将返回 `pg_catalog` schema 以及当前 schema。

## 返回类型
<a name="r_CURRENT_SCHEMAS-return-type"></a>

返回 CHAR 或 VARCHAR 字符串。

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

以下示例返回当前搜索路径中的 schemas（不包括隐式包含的系统 schemas）的名称：

```
select current_schemas(false);

current_schemas
-----------------
{public}
(1 row)
```

以下示例返回当前搜索路径中的 schemas（包括隐式包含的系统 schemas）的名称：

```
select current_schemas(true);

current_schemas
---------------------
{pg_catalog,public}
(1 row)
```

# CURRENT\$1SESSION\$1ARN
<a name="r_CURRENT_SESSION_ARN"></a>

返回当前已授权全局用户的 ARN。在所有 Redshift 账户、集群和 Serverless 工作组中，全局用户使用相同的身份。全局用户通过 IAM Identity Center 或基于 IAM 的会话身份验证登录。数据湖用户是全局 AWS 用户。

此函数通常在使用多方言 AWS Glue 视图的上下文中使用。有关使用 IAM Identity Center 和 Redshift 进行身份管理的更多信息，请参阅[将 Redshift 与 IAM Identity Center 连接，为用户提供单点登录体验](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-idp-connect.html)。有关多方言 Glue 视图的更多信息，请参阅[在 AWS Glue Data Catalog 中创建视图](https://docs.aws.amazon.com/redshift/latest/dg/data-catalog-views-overview.html)。

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

```
current_session_arn()
```

## 返回类型
<a name="r_CURRENT_SESSION_ARN-return-type"></a>

返回经过全局身份验证的用户的 VARCHAR 字符串或空值。

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

不支持本地用户，使用本地用户会返回空响应。

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

以下查询返回当前会话 ARN 的名称：

```
SELECT current_session_arn();

current_session_arn
--------------
arn:aws:iam::123456789012:user/user
(1 row)
```

# CURRENT\$1USER
<a name="r_CURRENT_USER"></a>

返回数据库的当前“有效”用户的用户名，视检查权限而定。通常，此用户名将与会话用户的相同；但是，此用户名偶尔可能被超级用户更改。

**注意**  
请勿在调用 CURRENT\$1USER 时使用尾随圆括号。

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

```
current_user
```

## 返回类型
<a name="r_CURRENT_USER-return-type"></a>

CURRENT\$1USER 返回 NAME 数据类型，可以将其转换为 CHAR 或 VARCHAR 字符串。

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

如果存储过程是使用 CREATE\$1PROCEDURE 命令的 SECURITY DEFINER 选项创建的，则从存储过程内调用 CURRENT\$1USER 函数时，Amazon Redshift 会返回存储过程拥有者的用户名。

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

以下查询返回当前数据库用户的名称：

```
select current_user;

current_user
--------------
dwuser
(1 row)
```

# CURRENT\$1USER\$1ID
<a name="r_CURRENT_USER_ID"></a>

返回登录到当前会话的 Amazon Redshift 用户的唯一标识符。

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

```
CURRENT_USER_ID
```

## 返回类型
<a name="r_CURRENT_USER_ID-return-type"></a>

CURRENT\$1USER\$1ID 函数返回整数。

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

以下示例返回此会话的用户名和当前用户 ID：

```
select user, current_user_id;

 current_user | current_user_id
--------------+-----------------
   dwuser     |               1
(1 row)
```

# DEFAULT\$1IAM\$1ROLE
<a name="r_DEFAULT_IAM_ROLE"></a>

返回当前与 Amazon Redshift 集群关联的默认 IAM 角色。如果没有任何关联的默认 IAM 角色，该函数将不返回任何内容。

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

```
select default_iam_role();
```

## 返回类型
<a name="r_DEFAULT_IAM_ROLE-return-type"></a>

返回 VARCHAR 字符串。

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

以下示例返回了当前与指定的 Amazon Redshift 集群关联的默认 IAM 角色，

```
select default_iam_role();
              default_iam_role
-----------------------------------------------
 arn:aws:iam::123456789012:role/myRedshiftRole
(1 row)
```

# GET\$1MOUNTED\$1ROLE
<a name="GET_MOUNTED_ROLE"></a>

 在作为多方言 AWS Glue 视图的一部分调用时，该参数允许返回用于挂载 Lake Formation 架构或数据库的 IAM 角色。多方言意味着多种查询引擎（如 Amazon EMR 和 Redshift）均支持该 SQL。有关多方言 Glue 视图的更多信息，请参阅[在 AWS Glue Data Catalog 中创建视图](https://docs.aws.amazon.com/redshift/latest/dg/data-catalog-views-overview.html)。



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

```
get_mounted_role()
```

## 返回类型
<a name="GET_MOUNTED_ROLE-return-type"></a>

返回 VARCHAR 字符串或空值。

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

对于外部 Lake Formation 视图之外的任何应用场景，此函数均返回空值。

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

以下查询返回用于挂载 Lake Formation 资源的身份。

```
CREATE EXTERNAL PROTECTED VIEW external_schema.remote_view AS 
SELECT mycol, get_mounted_role() FROM external_schema.remote_table;

mycol | get_mounted_role
----------------------------
1       arn:aws:iam::123456789012:role/salesrole
(1 row)
```

# HAS\$1ASSUMEROLE\$1PRIVILEGE
<a name="r_HAS_ASSUMEROLE_PRIVILEGE"></a>

如果指定用户具有指定 IAM 角色并具有运行指定命令的权限，则返回 Boolean `true`（`t`）。如果用户不具有指定 IAM 角色但具有运行指定命令的权限，函数将返回 `false`（`f`）。有关权限的更多信息，请参阅 [GRANT](r_GRANT.md)。

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

```
has_assumerole_privilege( [ user, ] iam_role_arn, cmd_type)
```

## 参数
<a name="r_HAS_ASSUMEROLE_PRIVILEGE-arguments"></a>

 *用户*   
要接受 IAM 角色权限检查的用户名称。默认为检查当前用户。超级用户和用户可以使用此函数。但是，用户只能查看自己的权限。

 *iam\$1role\$1arn*   
已被授予命令权限的 IAM 角色。

 *cmd\$1type*   
已授予访问权限的命令。有效值如下所示：  
+ COPY
+ UNLOAD
+ EXTERNAL FUNCTION
+ CREATE MODEL

## 返回类型
<a name="r_HAS_ASSUMEROLE_PRIVILEGE-return-type"></a>

BOOLEAN

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

以下查询确认用户 `reg_user1` 具有运行 COPY 命令的 `Redshift-S3-Read` 角色的权限。

```
select has_assumerole_privilege('reg_user1', 'arn:aws:iam::123456789012:role/Redshift-S3-Read', 'copy');
```

```
has_assumerole_privilege
------------------------
true
(1 row)
```

# HAS\$1DATABASE\$1PRIVILEGE
<a name="r_HAS_DATABASE_PRIVILEGE"></a>

如果用户对指定数据库具有指定特权，则返回 `true`。有关权限的更多信息，请参阅 [GRANT](r_GRANT.md)。

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

**注意**  
这是领导节点函数。如果此函数引用了用户创建的表、STL/STV 系统表或 SVV/SVL 系统视图，它将返回错误。

```
has_database_privilege( [ user, ] database, privilege)
```

## 参数
<a name="r_HAS_DATABASE_PRIVILEGE-arguments"></a>

 *用户*   
要接受数据库权限检查的用户的名称。默认为检查当前用户。

 *数据库*   
与特权关联的数据库。

 *privilege*   
要检查的特权。有效值如下所示：  
+ CREATE
+ TEMPORARY
+ TEMP

## 返回类型
<a name="r_HAS_DATABASE_PRIVILEGE-return-type"></a>

返回 CHAR 或 VARCHAR 字符串。

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

以下查询确认 GUEST 用户对 TICKIT 数据库具有 TEMP 特权。

```
select has_database_privilege('guest', 'tickit', 'temp');

has_database_privilege
------------------------
true
(1 row)
```

# HAS\$1SCHEMA\$1PRIVILEGE
<a name="r_HAS_SCHEMA_PRIVILEGE"></a>

如果用户对指定 schema 具有指定特权，则返回 `true`。有关权限的更多信息，请参阅 [GRANT](r_GRANT.md)。

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

**注意**  
这是领导节点函数。如果此函数引用了用户创建的表、STL/STV 系统表或 SVV/SVL 系统视图，它将返回错误。

```
has_schema_privilege( [ user, ] schema, privilege)
```

## 参数
<a name="r_HAS_SCHEMA_PRIVILEGE-arguments"></a>

 *用户*   
要接受 schema 特权检查的用户的名称。默认为检查当前用户。

 *schema*   
与特权关联的 Schema。

 *privilege*   
要检查的特权。有效值如下所示：  
+ CREATE
+ USAGE
+ ALTER
+ DROP

## 返回类型
<a name="r_HAS_SCHEMA_PRIVILEGE-return-type"></a>

返回 CHAR 或 VARCHAR 字符串。

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

以下查询确认 GUEST 用户对 PUBLIC schema 具有 CREATE 特权：

```
select has_schema_privilege('guest', 'public', 'create');

has_schema_privilege
----------------------
true
(1 row)
```

# HAS\$1TABLE\$1PRIVILEGE
<a name="r_HAS_TABLE_PRIVILEGE"></a>

如果用户对指定的表具有指定特权，则返回 `true`，否则返回 `false`。

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

**注意**  
这是领导节点函数。如果此函数引用了用户创建的表、STL/STV 系统表或 SVV/SVL 系统视图，它将返回错误。有关权限的更多信息，请参阅 [GRANT](r_GRANT.md)。

```
has_table_privilege( [ user, ] table, privilege)
```

## 参数
<a name="r_HAS_TABLE_PRIVILEGE-arguments"></a>

 *用户*   
要接受表特权检查的用户的名称。默认为检查当前用户。

 *table*   
与特权关联的表。

 *privilege*   
要检查的特权。有效值如下所示：  
+ SELECT
+ INSERT
+ UPDATE
+ DELETE
+ DROP
+ REFERENCES

## 返回类型
<a name="r_HAS_TABLE_PRIVILEGE-return-type"></a>

BOOLEAN

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

以下查询发现 GUEST 用户对 LISTING 表没有 SELECT 特权。

```
select has_table_privilege('guest', 'listing', 'select');

has_table_privilege
---------------------
false
```

以下查询使用 pg\$1tables 和 pg\$1user 目录表的输出来列出表权限，包括选择、插入、更新和删除。这只是一个示例。您可能需要指定数据库中的架构名称和表名。有关更多信息，请参阅 [查询目录表](c_join_PG.md)。

```
SELECT 
     tablename
     ,usename
     ,HAS_TABLE_PRIVILEGE(users.usename, tablename, 'select') AS sel
     ,HAS_TABLE_PRIVILEGE(users.usename, tablename, 'insert') AS ins
     ,HAS_TABLE_PRIVILEGE(users.usename, tablename, 'update') AS upd
     ,HAS_TABLE_PRIVILEGE(users.usename, tablename, 'delete') AS del
FROM
(SELECT * from pg_tables
WHERE schemaname = 'public' and tablename in ('event','listing')) as tables
,(SELECT * FROM pg_user) AS users;

tablename | usename   |  sel   |  ins  |  upd  | del
----------+-----------+--------+-------+-------+-------
event     |  john     |  true  | true  | true  | true	
event     |  sally    |  false | false | false | false	
event     |  elsa     |  false | false | false | false	
listing   |  john     |  true  | true  | true  | true	
listing   |  sally    |  false | false | false | false	
listing   |  elsa     |  false | false | false | false
```

前一个查询还包含交叉联接。有关更多信息，请参阅 [JOIN 示例](r_Join_examples.md)。要查询不在 `public` 架构中的表，请从 WHERE 子句中删除 `schemaname` 条件，并在查询之前使用以下示例。

```
SET SEARCH_PATH to 'schema_name';
```

# LAST\$1USER\$1QUERY\$1ID
<a name="LAST_USER_QUERY_ID"></a>

返回当前会话中最近完成的用户查询的查询 ID。如果当前会话中尚未运行任何查询，last\$1user\$1query\$1id 将返回 -1。此函数不会返回以独占方式在领导节点上运行的查询的查询 ID。有关更多信息，请参阅 [仅领导节点函数](c_SQL_functions_leader_node_only.md)。

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

```
last_user_query_id()
```

## 返回类型
<a name="LAST_USER_QUERY_ID-return-type"></a>

返回整数。

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

以下查询返回由用户在当前会话中运行的最近完成的查询的 ID。

```
select last_user_query_id();
```

结果如下。

```
last_user_query_id
-----------------------
    5437
(1 row)
```

以下查询返回由用户在当前会话中运行的最近完成的查询的查询 ID 和文本。

```
select query_id, query_text from sys_query_history where query_id = last_user_query_id();
```

结果如下。

```
 query_id, query_text
---------+-------------------------------------------------------------------------------------------------------------
 5556975 | select last_user_query_id() limit 100 --RequestID=<unique request ID>; TraceID=<unique trace ID>
```

# PG\$1BACKEND\$1PID
<a name="PG_BACKEND_PID"></a>

返回处理当前会话的服务器进程的进程 ID (PID)。

**注意**  
PID 不是全局唯一的。它可以在一段时间后重复使用。

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

```
pg_backend_pid()
```

## 返回类型
<a name="PG_BACKEND_PID-return-type"></a>

返回整数。

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

您可将 PG\$1BACKEND\$1PID 与日志表关联以检索当前会话的信息。例如，以下查询返回当前会话中完成的查询的查询 ID 和一部分查询文本。

```
select query, substring(text,1,40)
from stl_querytext
where pid =  PG_BACKEND_PID()
order by query desc;

 query |                substring
-------+------------------------------------------
 14831 | select query, substring(text,1,40) from
 14827 | select query, substring(path,0,80) as pa
 14826 | copy category from 's3://dw-tickit/manif
 14825 | Count rows in target table
 14824 | unload ('select * from category') to 's3
(5 rows)
```

您可将 PG\$1BACKEND\$1PID 与以下日志表中的 pid 列关联（圆括号中指明的除外）：
+ [STL\$1CONNECTION\$1LOG](r_STL_CONNECTION_LOG.md)
+ [STL\$1DDLTEXT](r_STL_DDLTEXT.md)
+ [STL\$1ERROR](r_STL_ERROR.md)
+ [STL\$1QUERY](r_STL_QUERY.md)
+ [STL\$1QUERYTEXT](r_STL_QUERYTEXT.md)
+ [STL\$1SESSIONS](r_STL_SESSIONS.md) (process)
+ [STL\$1TR\$1CONFLICT](r_STL_TR_CONFLICT.md)
+ [STL\$1UTILITYTEXT](r_STL_UTILITYTEXT.md)
+ [STV\$1ACTIVE\$1CURSORS](r_STV_ACTIVE_CURSORS.md)
+ [STV\$1INFLIGHT](r_STV_INFLIGHT.md)
+ [STV\$1LOCKS](r_STV_LOCKS.md) (lock\$1owner\$1pid)
+ [STV\$1RECENTS](r_STV_RECENTS.md) (process\$1id)

# PG\$1GET\$1COLS
<a name="PG_GET_COLS"></a>

返回表或视图定义的列元数据。

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

```
pg_get_cols('name')
```

## 参数
<a name="PG_GET_COLS-arguments"></a>

 *名称*   
Amazon Redshift 表或视图的名称。有关更多信息，请参阅 [名称和标识符](r_names.md)。

## 返回类型
<a name="PG_GET_COLS-return-type"></a>

VARCHAR 

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

PG\$1GET\$1COLS 函数为表或视图定义中的每个列返回一行内容。该行包含一个逗号分隔列表，其中包括 schema 名称、关系名称、列名、数据类型和列编号。SQL 结果的格式取决于所使用的 SQL 客户端。

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

以下示例返回针对模式 `public` 中名为 `SALES_VW` 的视图和模式 `mytickit1` 中名为 `sales` 的表的结果，相应的视图和表由用户在连接的数据库 `dev` 中创建。

以下示例会返回名为 `SALES_VW` 的视图的列元数据。

```
select pg_get_cols('sales_vw');

pg_get_cols                                                
-----------------------------------------------------------
(public,sales_vw,salesid,integer,1)                        
(public,sales_vw,listid,integer,2)                         
(public,sales_vw,sellerid,integer,3)                       
(public,sales_vw,buyerid,integer,4)                        
(public,sales_vw,eventid,integer,5)                        
(public,sales_vw,dateid,smallint,6)                        
(public,sales_vw,qtysold,smallint,7)                       
(public,sales_vw,pricepaid,"numeric(8,2)",8)               
(public,sales_vw,commission,"numeric(8,2)",9)              
(public,sales_vw,saletime,"timestamp without time zone",10)
```

以下示例会以表格式返回 `SALES_VW` 视图的列元数据。

```
select * from pg_get_cols('sales_vw') 
cols(view_schema name, view_name name, col_name name, col_type varchar, col_num int);

view_schema | view_name | col_name   | col_type                    | col_num
------------+-----------+------------+-----------------------------+--------
public      | sales_vw  | salesid    | integer                     |       1
public      | sales_vw  | listid     | integer                     |       2
public      | sales_vw  | sellerid   | integer                     |       3
public      | sales_vw  | buyerid    | integer                     |       4
public      | sales_vw  | eventid    | integer                     |       5
public      | sales_vw  | dateid     | smallint                    |       6
public      | sales_vw  | qtysold    | smallint                    |       7
public      | sales_vw  | pricepaid  | numeric(8,2)                |       8
public      | sales_vw  | commission | numeric(8,2)                |       9
public      | sales_vw  | saletime   | timestamp without time zone |      10
```

以下示例会以表格式返回架构 `mytickit1` 中 `SALES` 表的列元数据。

```
select * from pg_get_cols('"mytickit1"."sales"') 
cols(view_schema name, view_name name, col_name name, col_type varchar, col_num int);

view_schema | view_name | col_name   | col_type                    | col_num
------------+-----------+------------+-----------------------------+--------
mytickit1   | sales     | salesid    | integer                     |       1
mytickit1   | sales     | listid     | integer                     |       2
mytickit1   | sales     | sellerid   | integer                     |       3
mytickit1   | sales     | buyerid    | integer                     |       4
mytickit1   | sales     | eventid    | integer                     |       5
mytickit1   | sales     | dateid     | smallint                    |       6
mytickit1   | sales     | qtysold    | smallint                    |       7
mytickit1   | sales     | pricepaid  | numeric(8,2)                |       8
mytickit1   | sales     | commission | numeric(8,2)                |       9
mytickit1   | sales     | saletime   | timestamp without time zone |      10
```

# PG\$1GET\$1GRANTEE\$1BY\$1IAM\$1ROLE
<a name="PG_GET_GRANTEE_BY_IAMROLE"></a>

返回被授予指定 IAM 角色的所有用户和组。

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

```
pg_get_grantee_by_iam_role('iam_role_arn')
```

## 参数
<a name="PG_GET_GRANTEE_BY_IAMROLE-arguments"></a>

 *iam\$1role\$1arn*   
用于返回已被授予此角色的用户和组的 IAM 角色。

## 返回类型
<a name="PG_GET_GRANTEE_BY_IAMROLE-return-type"></a>

VARCHAR 

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

PG\$1GET\$1GRANTEE\$1BY\$1IAM\$1ROLE 函数为每个用户或组返回一行。每行都包含被授权者名称、被授权者类型和授予的权限。被授权者类型的可能值如下：对于公有为 `p`，对于用户为 `u`，对于组为 `g`。

您必须是超级用户才能使用函数。

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

以下示例指示 IAM 角色 `Redshift-S3-Write` 被授予给 `group1` 和 `reg_user1`。`group_1` 中的用户只能为 COPY 操作指定角色，用户 `reg_user1` 可以指定仅用于执行 UNLOAD 操作的角色。

```
select pg_get_grantee_by_iam_role('arn:aws:iam::123456789012:role/Redshift-S3-Write');
```

```
  pg_get_grantee_by_iam_role
-----------------------------
 (group_1,g,COPY)
 (reg_user1,u,UNLOAD)
```

下面的 PG\$1GET\$1GRANTEE\$1BY\$1IAM\$1ROLE 函数示例将结果格式化为表格。

```
select grantee, grantee_type, cmd_type FROM pg_get_grantee_by_iam_role('arn:aws:iam::123456789012:role/Redshift-S3-Write') res_grantee(grantee text, grantee_type text, cmd_type text) ORDER BY 1,2,3;
```

```
  grantee  | grantee_type | cmd_type
-----------+--------------+----------
 group_1   | g            | COPY
 reg_user1 | u            | UNLOAD
```

# PG\$1GET\$1IAM\$1ROLE\$1BY\$1USER
<a name="PG_GET_IAM_ROLE_BY_USER"></a>

返回授予用户的所有 IAM 角色和命令权限。

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

```
pg_get_iam_role_by_user('name')
```

## 参数
<a name="PG_GET_IAM_ROLE_BY_USER-arguments"></a>

 *名称*   
要返回 IAM 角色的用户的名称。

## 返回类型
<a name="PG_GET_IAM_ROLE_BY_USER-return-type"></a>

VARCHAR 

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

PG\$1GET\$1IAM\$1ROLE\$1BY\$1USER 函数为每组角色和命令特权返回一行。该行包含一个逗号分隔列表，其中包括用户名、IAM 角色和命令。

结果中的值 `default` 表示用户可以指定任何可用角色来执行显示的命令。

您必须是超级用户才能使用函数。

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

以下示例指示用户 `reg_user1` 可以指定任何可用的 IAM 角色来执行 COPY 操作。用户也可以指定 `Redshift-S3-Write` 角色进行 UNLOAD 操作。

```
select pg_get_iam_role_by_user('reg_user1');
```

```
                             pg_get_iam_role_by_user
---------------------------------------------------------------------------------
 (reg_user1,default,COPY)
 (reg_user1,arn:aws:iam::123456789012:role/Redshift-S3-Write,COPY|UNLOAD)
```

下面的 PG\$1GET\$1IAM\$1ROLE\$1BY\$1USER 函数示例将结果格式化为表格。

```
select username, iam_role, cmd FROM pg_get_iam_role_by_user('reg_user1') res_iam_role(username text, iam_role text, cmd text);
```

```
 username  |                    iam_role                     | cmd
-----------+-------------------------------------------------+------
 reg_user1 | default                                         | None
 reg_user1 | arn:aws:iam::123456789012:role/Redshift-S3-Read | COPY
```

# PG\$1GET\$1LATE\$1BINDING\$1VIEW\$1COLS
<a name="PG_GET_LATE_BINDING_VIEW_COLS"></a>

返回数据库中所有后期绑定视图的列元数据。有关更多信息，请参阅[后期绑定视图](r_CREATE_VIEW.md#r_CREATE_VIEW_late-binding-views)。

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

```
pg_get_late_binding_view_cols()
```

## 返回类型
<a name="PG_GET_LATE_BINDING_VIEW_COLS-return-type"></a>

VARCHAR 

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

`PG_GET_LATE_BINDING_VIEW_COLS` 函数为后期绑定视图中的每个列返回一行内容。该行包含一个逗号分隔列表，其中包括 schema 名称、关系名称、列名、数据类型和列编号。

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

以下示例返回所有后期绑定视图的列元数据。

```
select pg_get_late_binding_view_cols();

pg_get_late_binding_view_cols                               
------------------------------------------------------------
(public,myevent,eventname,"character varying(200)",1)       
(public,sales_lbv,salesid,integer,1)                        
(public,sales_lbv,listid,integer,2)                         
(public,sales_lbv,sellerid,integer,3)                       
(public,sales_lbv,buyerid,integer,4)                        
(public,sales_lbv,eventid,integer,5)                        
(public,sales_lbv,dateid,smallint,6)                        
(public,sales_lbv,qtysold,smallint,7)                       
(public,sales_lbv,pricepaid,"numeric(8,2)",8)               
(public,sales_lbv,commission,"numeric(8,2)",9)              
(public,sales_lbv,saletime,"timestamp without time zone",10)
(public,event_lbv,eventid,integer,1)                        
(public,event_lbv,venueid,smallint,2)                       
(public,event_lbv,catid,smallint,3)                         
(public,event_lbv,dateid,smallint,4)                        
(public,event_lbv,eventname,"character varying(200)",5)     
(public,event_lbv,starttime,"timestamp without time zone",6)
```

以下示例以表格式返回所有后期绑定视图的列元数据。

```
select * from pg_get_late_binding_view_cols() cols(view_schema name, view_name name, col_name name, col_type varchar, col_num int);
view_schema | view_name | col_name   | col_type                    | col_num
------------+-----------+------------+-----------------------------+--------
public      | sales_lbv | salesid    | integer                     |       1
public      | sales_lbv | listid     | integer                     |       2
public      | sales_lbv | sellerid   | integer                     |       3
public      | sales_lbv | buyerid    | integer                     |       4
public      | sales_lbv | eventid    | integer                     |       5
public      | sales_lbv | dateid     | smallint                    |       6
public      | sales_lbv | qtysold    | smallint                    |       7
public      | sales_lbv | pricepaid  | numeric(8,2)                |       8
public      | sales_lbv | commission | numeric(8,2)                |       9
public      | sales_lbv | saletime   | timestamp without time zone |      10
public      | event_lbv | eventid    | integer                     |       1
public      | event_lbv | venueid    | smallint                    |       2
public      | event_lbv | catid      | smallint                    |       3
public      | event_lbv | dateid     | smallint                    |       4
public      | event_lbv | eventname  | character varying(200)      |       5
public      | event_lbv | starttime  | timestamp without time zone |       6
```

# PG\$1GET\$1SESSION\$1ROLES
<a name="PG_GET_SESSION_ROLES"></a>

返回当前登录的用户的会话角色。用户的会话角色是由身份提供者 (IdP) 为登录用户定义的组。例如，身份提供者 (IdP)（如 [Microsoft Azure Active Directory (Azure AD)](https://azure.microsoft.com/en-us/services/active-directory/)）验证用户的身份，并在用户登录过程中提供该用户所属的所有外部组。这些外部组转换为 Amazon Redshift 角色，可在当前会话期间使用。这些角色称为会话角色。管理员可以向会话角色授予与其他 Amazon Redshift 角色类似的权限。有关使用角色的信息，请参阅[基于角色的访问控制 (RBAC)](t_Roles.md)。有关使用身份提供者 (IdP) 管理身份的信息，请参阅《Amazon Redshift 管理指南》**中的 [Amazon Redshift 的原生身份提供者 (IdP) 联合身份验证](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-native-idp.html)。

要查看 Amazon Redshift 目录中定义的角色，请查询系统视图 [SVV\$1ROLES](r_SVV_ROLES.md)。

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

```
pg_get_session_roles()
```

## 返回类型
<a name="PG_GET_SESSION_ROLES-return-type"></a>

一组由两个值组成的行。第一个值由两部分组成，用冒号 (:) 分隔，其中包含 `idp-namespace:role-name`。`idp-namespace` 是身份提供者 (IdP) 的命名空间。`role-name` 是身份提供者 (IdP) 中的外部组的名称。第二个值包含作为角色标识符的 `role-id`。

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

`PG_GET_SESSION_ROLES` 函数为每个返回的会话角色返回一行。

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

以下示例为 Azure Active Directory IdP 中的每个角色返回一行。返回的列强制转换为 `sess_roles`，列为 `name` 和 `roleid`。每个 `name` 由 Azure Active Directory 命名空间和 Azure Active Directory 中的组名称组成。

```
SELECT * FROM pg_get_session_roles() AS sess_roles(name name, roleid integer);

name                  roleid
--------------------------------
my_aad:test_group_1   106204
my_aad:test_group_2   106205
my_aad:test_group_3   106206
my_aad:test_group_4   106207
my_aad:test_group_5   106208
```

以下示例为当前登录的 IAM 用户所属的每个 IAM 组返回一行。返回的列强制转换为 `sess_roles`，列为 `name` 和 `roleid`。每个 `name` 由 IAM 命名空间和 IAM 组名称组成。

```
SELECT * FROM pg_get_session_roles() AS sess_roles(name name, roleid integer);

name                  roleid
--------------------------------
IAM:myGroup           110332
```

# PG\$1LAST\$1COPY\$1COUNT
<a name="PG_LAST_COPY_COUNT"></a>

返回由当前会话中运行的上一条 COPY 命令加载的行的数量。将使用上一个 COPY ID（开始加载过程的上一个 COPY 的查询 ID）更新 PG\$1LAST\$1COPY\$1COUNT，即使加载失败也是如此。当 COPY 命令开始加载过程时，将更新查询 ID 和 COPY ID。

如果 COPY 因语法错误或权限不足而失败，则不会更新 COPY ID 并且 PG\$1LAST\$1COPY\$1COUNT 将返回上一个 COPY 的计数。如果未在当前会话中运行任何 COPY 命令，或如果上一个 COPY 在加载过程中失败，PG\$1LAST\$1COPY\$1COUNT 将返回 0。有关更多信息，请参阅 [PG\$1LAST\$1COPY\$1ID](PG_LAST_COPY_ID.md)。

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

```
pg_last_copy_count()
```

## 返回类型
<a name="PG_LAST_COPY_COUNT-return-type"></a>

返回 BIGINT。

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

以下查询返回由当前会话中的最新 COPY 命令加载的行的数量。

```
select pg_last_copy_count();

pg_last_copy_count
--------------------
             192497
(1 row)
```

# PG\$1LAST\$1COPY\$1ID
<a name="PG_LAST_COPY_ID"></a>

返回当前会话中最近完成的 COPY 命令的查询 ID。如果当前会话中尚未运行任何 COPY 命令，PG\$1LAST\$1COPY\$1ID 将返回 -1。

 当 COPY 命令开始加载过程时，将更新 PG\$1LAST\$1COPY\$1ID 的值。如果 COPY 因加载数据无效而失败，则会更新 COPY ID，因此您可在查询 STL\$1LOAD\$1ERRORS 表时使用 PG\$1LAST\$1COPY\$1ID。如果回滚了 COPY 事务，则不会更新 COPY ID。

如果 COPY 命令因加载过程开始前出现的错误（如语法错误、访问错误、凭证无效或权限不足）而失败，则不会更新 COPY ID。如果 COPY 在分析压缩步骤（在成功连接之后、数据加载之前开始）中失败，则将不会更新 COPY ID。

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

```
pg_last_copy_id()
```

## 返回类型
<a name="PG_LAST_COPY_ID-return-type"></a>

返回整数。

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

以下查询返回当前会话中的最新 COPY 命令的查询 ID。

```
select pg_last_copy_id();

pg_last_copy_id
---------------
          5437
(1 row)
```

以下查询将 STL\$1LOAD\$1ERRORS 联接到 STL\$1LOADERROR\$1DETAIL 以查看当前会话中的最近一次加载过程中发生的错误的详细信息：

```
select d.query, substring(d.filename,14,20), 
d.line_number as line, 
substring(d.value,1,16) as value,
substring(le.err_reason,1,48) as err_reason
from stl_loaderror_detail d, stl_load_errors le
where d.query = le.query
and d.query = pg_last_copy_id(); 

 query |    substring      | line |  value   |                    err_reason
-------+-------------------+------+----------+-------------------------------------------------
    558| allusers_pipe.txt |  251 | 251      | String contains invalid or unsupported UTF8 code
    558| allusers_pipe.txt |  251 | ZRU29FGR | String contains invalid or unsupported UTF8 code
    558| allusers_pipe.txt |  251 | Kaitlin  | String contains invalid or unsupported UTF8 code
    558| allusers_pipe.txt |  251 | Walter   | String contains invalid or unsupported UTF8 code
```

# PG\$1LAST\$1UNLOAD\$1ID
<a name="PG_LAST_UNLOAD_ID"></a>

返回当前会话中最近完成的 UNLOAD 命令的查询 ID。如果当前会话中未运行任何 UNLOAD 命令，则 PG\$1LAST\$1UNLOAD\$1ID 将返回 -1。

 当 UNLOAD 命令开始加载过程时，将更新 PG\$1LAST\$1UNLOAD\$1ID 的值。如果 UNLOAD 因加载数据无效而失败，则将更新 UNLOAD ID，以便您能使用 UNLOAD ID 进行进一步调查。如果回滚 UNLOAD 事务，则不会更新 UNLOAD ID。

如果 UNLOAD 命令因加载过程开始前出现的错误（如语法错误、访问错误、凭证无效或权限不足）而失败，则不会更新 UNLOAD ID。

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

```
PG_LAST_UNLOAD_ID()
```

## 返回类型
<a name="PG_LAST_UNLOAD_ID-return-type"></a>

返回整数。

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

以下查询返回当前会话中的最新 UNLOAD 命令的查询 ID。

```
select PG_LAST_UNLOAD_ID();

PG_LAST_UNLOAD_ID
---------------
          5437
(1 row)
```

# PG\$1LAST\$1QUERY\$1ID
<a name="PG_LAST_QUERY_ID"></a>

返回当前会话中最近完成的查询的查询 ID。如果当前会话中尚未运行任何查询，PG\$1LAST\$1QUERY\$1ID 将返回 -1。PG\$1LAST\$1QUERY\$1ID 不会返回以独占方式在领导节点上运行的查询的查询 ID。有关更多信息，请参阅 [仅领导节点函数](c_SQL_functions_leader_node_only.md)。

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

```
pg_last_query_id()
```

## 返回类型
<a name="PG_LAST_QUERY_ID-return-type"></a>

返回整数。

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

以下查询返回当前会话中最近完成的查询的 ID。

```
select pg_last_query_id();
```

结果如下。

```
pg_last_query_id
----------------
           5437
(1 row)
```

以下查询返回当前会话中最近完成的查询的查询 ID 和文本。

```
select query, trim(querytxt) as sqlquery
from stl_query
where query = pg_last_query_id();
```

结果如下。

```
query | sqlquery
------+--------------------------------------------------
 5437 | select name, loadtime from stl_file_scan where loadtime > 1000000;
(1 rows)
```

# PG\$1LAST\$1UNLOAD\$1COUNT
<a name="PG_LAST_UNLOAD_COUNT"></a>

返回由当前会话中完成的上一条 UNLOAD 命令卸载的行的数量。将使用上一个 UNLOAD 的查询 ID 更新 PG\$1LAST\$1UNLOAD\$1COUNT，即使操作失败也是如此。将在完成 UNLOAD 时更新此查询 ID。如果 UNLOAD 因语法错误或权限不足而失败，PG\$1LAST\$1UNLOAD\$1COUNT 将返回上一个 UNLOAD 的计数。如果当前会话中尚未完成 UNLOAD 命令，或如果上一个 UNLOAD 在卸载操作期间失败，PG\$1LAST\$1UNLOAD\$1COUNT 将返回 0。

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

```
pg_last_unload_count()
```

## 返回类型
<a name="PG_LAST_UNLOAD_COUNT-return-type"></a>

返回 BIGINT。

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

以下查询返回当前会话中的最新 UNLOAD 命令卸载的行的数量。

```
select pg_last_unload_count();

pg_last_unload_count
--------------------
             192497
(1 row)
```

# SLICE\$1NUM 函数
<a name="r_SLICE_NUM"></a>

返回一个整数，该整数对应于某个行的数据所在的集群中的切片数。SLICE\$1NUM 未采用任何参数。

## 语法
<a name="r_SLICE_NUM-syntax"></a>

```
SLICE_NUM()
```

## 返回类型
<a name="r_SLICE_NUM-return-type"></a>

SLICE\$1NUM 函数返回整数。

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

以下示例显示包含 EVENTS 中前十个 EVENT 行的数据的切片：

```
select distinct eventid, slice_num() from event order by eventid limit 10;

 eventid | slice_num
---------+-----------
       1 |         1
       2 |         2
       3 |         3
       4 |         0
       5 |         1
       6 |         2
       7 |         3
       8 |         0
       9 |         1
      10 |         2
(10 rows)
```

以下示例将返回一个代码 (10000) 以演示没有 FROM 语句的查询是如何在领导节点上运行的：

```
select slice_num();
slice_num
-----------
10000
(1 row)
```

# USER
<a name="r_USER"></a>

CURRENT\$1USER 的同义词。请参阅[CURRENT\$1USER](r_CURRENT_USER.md)。

# ROLE\$1IS\$1MEMBER\$1OF
<a name="r_ROLE_IS_MEMBER_OF"></a>

如果角色是其他角色的成员，则返回 true。超级用户可以检查所有角色的成员身份。具有 ACCESS SYSTEM TABLE 权限的普通用户可以检查所有用户的成员身份。否则，普通用户只能检查其具有访问权限的角色。如果提供的角色不存在或当前用户无权访问该角色，则 Amazon Redshift 会返回错误。

**数据共享注意事项**

当使用者集群查询引用此函数的共享对象（例如视图、RLS 策略或 DDM 策略）时，该函数将利用使用者集群的安全上下文进行评估。结果由使用者的本地用户、角色和组成员资格决定，而不是由在生产者集群上定义的用户、角色和组成员资格决定。如果您打算强制执行在生产者上实施的相同权限上下文，请确保使用者集群上存在相应的角色名、组名和用户成员资格，并且与生产者上的角色名、组名和用户成员资格相匹配。

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

```
role_is_member_of( role_name,  granted_role_name)
```

## 参数
<a name="r_ROLE_IS_MEMBER_OF-arguments"></a>

 *role\$1name*   
角色的名称。

 *granted\$1role\$1name*   
所授予角色的名称。

## 返回类型
<a name="r_ROLE_IS_MEMBER_OF-return-type"></a>

返回一个布尔值。

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

以下查询确认该角色不是 role1 的成员，也不是 role2 的成员。

```
SELECT role_is_member_of('role1', 'role2');

 role_is_member_of
-------------------
             False
```

# USER\$1IS\$1MEMBER\$1OF
<a name="r_USER_IS_MEMBER_OF"></a>

**重要**  
从 2026 年 2 月 16 日起，Amazon Redshift 将不再支持使用 `user_is_member_of` 以及通过数据共享访问使用者用户、角色或组信息的相关函数。

如果用户是某个角色或组的成员，则返回 true。超级用户可以检查所有用户的成员身份。属于 sy:secadmin 或 sys:superuser 角色成员的普通用户可以检查所有用户的成员身份。否则，普通用户只能检查自己的成员身份。如果提供的身份不存在或当前用户无权访问该角色，则 Amazon Redshift 会发出错误消息。

**数据共享注意事项**

当使用者集群查询引用此函数的共享对象（例如视图、RLS 策略或 DDM 策略）时，该函数将利用使用者集群的安全上下文进行评估。结果由使用者的本地用户、角色和组成员资格决定，而不是由在生产者集群上定义的用户、角色和组成员资格决定。如果您打算强制执行在生产者上实施的相同权限上下文，请确保使用者集群上存在相应的角色名、组名和用户成员资格，并且与生产者上的角色名、组名和用户成员资格相匹配。

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

```
user_is_member_of( user_name,  role_name | group_name)
```

## 参数
<a name="r_USER_IS_MEMBER_OF-arguments"></a>

 *user\$1name*   
用户的名称。

 *role\$1name*   
角色的名称。

 *group\$1name*   
组的名称。

## 返回类型
<a name="r_USER_IS_MEMBER_OF-return-type"></a>

返回一个布尔值。

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

以下查询确认该用户不是 role1 的成员。

```
SELECT user_is_member_of('reguser', 'role1');

 user_is_member_of
-------------------
           False
```

# VERSION
<a name="r_VERSION"></a>

 VERSION 函数返回有关当前安装版本的详细信息（在末尾有特定的 Amazon Redshift 版本信息）。

**注意**  
这是领导节点函数。如果此函数引用了用户创建的表、STL/STV 系统表或 SVV/SVL 系统视图，它将返回错误。

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

```
VERSION()
```

## 返回类型
<a name="r_VERSION-return-type"></a>

返回 CHAR 或 VARCHAR 字符串。

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

以下示例显示了当前集群的集群版本信息：

```
select version();
```

```
 version
 ------------------------------------------------------------------------------------------------------------------------               
 PostgreSQL 8.0.2 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 3.4.2 20041017 (Red Hat 3.4.2-6.fc3), Redshift 1.0.12103
```

其中 `1.0.12103` 是集群版本号。

**注意**  
要强制您的集群更新到最新集群版本，请调整您的[维护时段](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html#rs-maintenance-windows)。

# 保留字
<a name="r_pg_keywords"></a>

下面是 Amazon Redshift 保留关键字的列表。您可以通过分隔标识符（双引号）使用保留关键字。

**注意**  
虽然 START 和 CONNECT 不是保留字，但如果您在查询中使用 START 和 CONNECT 作为表别名，请使用分隔标识符或 AS，以避免在运行时失败。

有关更多信息，请参阅 [名称和标识符](r_names.md)。

```
AES128
AES256
ALL
ALLOWOVERWRITE
ANALYSE
ANALYZE
AND
ANY
ARRAY
AS
ASC
AUTHORIZATION
AZ64
BACKUP
BETWEEN
BINARY
BLANKSASNULL
BOTH
BYTEDICT
BZIP2
CASE
CAST
CHECK
COLLATE
COLUMN
CONSTRAINT
CREATE
CREDENTIALS
CROSS
CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_USER
CURRENT_USER_ID
DEFAULT
DEFERRABLE
DEFLATE
DEFRAG
DELTA
DELTA32K
DESC
DISABLE
DISTINCT
DO
ELSE
EMPTYASNULL
ENABLE
ENCODE
ENCRYPT     
ENCRYPTION
END
EXCEPT
EXPLICIT
FALSE
FOR
FOREIGN
FREEZE
FROM
FULL
GLOBALDICT256
GLOBALDICT64K
GRANT
GROUP
GZIP
HAVING
IDENTITY
IGNORE
ILIKE
IN
INITIALLY
INNER
INTERSECT
INTERVAL
INTO
IS
ISNULL
JOIN
LEADING
LEFT
LIKE
LIMIT
LOCALTIME
LOCALTIMESTAMP
LUN
LUNS
LZO
LZOP
MINUS
MOSTLY16
MOSTLY32
MOSTLY8
NATURAL
NEW
NOT
NOTNULL
NULL
NULLS
OFF
OFFLINE
OFFSET
OID
OLD
ON
ONLY
OPEN
OR
ORDER
OUTER
OVERLAPS
PARALLEL
PARTITION
PERCENT
PERMISSIONS
PIVOT
PLACING
PRIMARY
RAW
READRATIO
RECOVER
REFERENCES
REJECTLOG
RESORT
RESPECT
RESTORE
RIGHT
SELECT
SESSION_USER
SIMILAR
SNAPSHOT 
SOME
SYSDATE
SYSTEM
TABLE
TAG
TDES
TEXT255
TEXT32K
THEN
TIMESTAMP
TO
TOP
TRAILING
TRUE
TRUNCATECOLUMNS
UNION
UNIQUE
UNNEST
UNPIVOT
USER
USING
VERBOSE
WALLET
WHEN
WHERE
WITH
WITHOUT
```