

# 使用联合传递查询
<a name="federated-query-passthrough"></a>

在 Athena 中，可以使用数据来源本身的查询语言对联合数据来源运行查询，并将完整查询下推到数据来源来执行查询。这些查询称为传递查询。要运行传递查询，可以在 Athena 查询中使用表函数。您可以将要在数据来源上运行的传递查询包含在表函数的其中一个参数中。传递查询会返回一个表，该表可以使用 Athena SQL 进行分析。

## 支持的连接器
<a name="federated-query-passthrough-supported-connectors"></a>

以下 Athena 数据来源连接器支持传递查询。
+ [Azure Data Lake 存储](connectors-adls-gen2.md)
+ [Azure Synapse](connectors-azure-synapse.md)
+ [Cloudera Hive](connectors-cloudera-hive.md)
+ [Cloudera Impala](connectors-cloudera-impala.md)
+ [CloudWatch](connectors-cloudwatch.md)
+ [Db2](connectors-ibm-db2.md)
+ [Db2 iSeries](connectors-ibm-db2-as400.md)
+ [DocumentDB](connectors-docdb.md) 
+ [DynamoDB](connectors-dynamodb.md) 
+ [HBase](connectors-hbase.md)
+ [Google BigQuery](connectors-bigquery.md)
+ [Hortonworks](connectors-hortonworks.md)
+ [MySQL](connectors-mysql.md)
+ [Neptune](connectors-neptune.md)
+ [OpenSearch](connectors-opensearch.md) 
+ [Oracle](connectors-oracle.md)
+ [PostgreSQL](connectors-postgresql.md)
+ [Redshift](connectors-redshift.md)
+ [SAP HANA](connectors-sap-hana.md)
+ [Snowflake](connectors-snowflake.md)
+ [SQL Server](connectors-microsoft-sql-server.md)
+ [Teradata](connectors-teradata.md)
+ [Timestream](connectors-timestream.md)
+ [Vertica](connectors-vertica.md)

## 注意事项和限制
<a name="federated-query-passthrough-considerations-and-limitations"></a>

在 Athena 中使用传递查询时，请注意以下几点：
+ 只有 Athena `SELECT` 语句或读取操作才支持查询传递。
+ 查询性能可能因数据来源的配置而异。
+ 查询传递功能不支持 Lake Formation 精细访问控制。
+ [注册为 Glue 数据目录](register-connection-as-gdc.md)的数据来源不支持传递查询。

## 语法
<a name="federated-query-passthrough-syntax"></a>

常规 Athena 查询传递语法如下所示：

```
SELECT * FROM TABLE(catalog.system.function_name(arg1 => 'arg1Value'[, arg2 => 'arg2Value', ...]))
```

请注意以下几点：
+ **目录**：目标 Athena 联合连接器名称或数据目录名称。
+ **系统**：包含函数的命名空间。所有 Athena 连接器实施均使用此命名空间。
+ **function\$1name**：将传递查询向下推送到数据来源的函数名称。这通常称为 `query`。`catalog.system.function_name` 组合是该函数的完整解析路径。
+ **arg1 和 arg2 等参数**：函数参数。用户必须将这些参数传递到函数。在大多数情况下，这是向下传递到数据来源的查询字符串。

对于大多数数据来源，第一个也是唯一的参数为 `query`，后跟箭头运算符 `=>` 和查询字符串。

```
SELECT * FROM TABLE(catalog.system.query(query => 'query string'))
```

为简单起见，可选的命名参数 `query` 和箭头运算符 `=>` 均可省略。

```
SELECT * FROM TABLE(catalog.system.query('query string'))
```

如果查询在目标目录的上下文中运行，则可以通过删除 `catalog` 名称来进一步简化查询。

```
SELECT * FROM TABLE(system.query('query string'))
```

如果数据来源需要的不仅仅是查询字符串，请按照数据来源所需的顺序使用命名参数。例如，表达式 `arg1 => 'arg1Value'` 包含第一个参数及其值。*arg1* 名称与数据来源相关，可能因连接器而异。

```
SELECT * FROM TABLE(
        system.query(
            arg1 => 'arg1Value',
            arg2 => 'arg2Value',
            arg3 => 'arg3Value'
        ));
```

也可以通过省略参数名称来简化上述步骤。但是，您必须遵循方法签名的顺序。有关函数签名的更多信息，请参阅每个连接器的文档。

```
SELECT * FROM TABLE(catalog.system.query('arg1Value', 'arg2Value', 'arg3Value'))
```

如下例所示，您可以使用完整的函数解析路径，跨不同 Athena 连接器运行多个传递查询。

```
SELECT c_customer_sk 
    FROM TABLE (postgresql.system.query('select * from customer limit 10'))
UNION
SELECT c_customer_sk 
    FROM TABLE(dynamodb.system.query('select * from customer')) LIMIT 10
```

您可以将传递查询作为联合视图的一部分使用。相同限制适用。有关更多信息，请参阅[查询联合视图](https://docs.amazonaws.cn/athena/latest/ug/running-federated-queries.html#running-federated-queries-federated-views)。

```
CREATE VIEW catalog.database.ViewName AS
    SELECT * FROM TABLE (
        catalog.system.query('query')
    )
```

有关用于特定连接器的确切语法的信息，请参阅相应连接器的文档。

### 引号用法
<a name="federated-query-passthrough-syntax-quotation-marks"></a>

必须用单引号将参数值（包含传递的查询字符串）括起来，如下例所示：

```
SELECT * FROM TABLE(system.query(query => 'SELECT * FROM testdb.persons LIMIT 10'))
```

如果使用双引号将查询字符串括起来，查询会失败。以下查询失败，显示错误消息：COLUMN\$1NOT\$1FOUND: line 1:43: Column 'select \$1 from testdb.persons limit 10' cannot be resolved。

```
SELECT * FROM TABLE(system.query(query => "SELECT * FROM testdb.persons LIMIT 10"))
```

要转义单引号，请在原始单引号中添加单引号（例如由 `terry's_group` 变为 `terry''s_group`）。

## 示例
<a name="federated-query-passthrough-sql-based-connectors-examples"></a>

以下示例查询将查询下推到数据来源。该查询选择了 `customer` 表中的所有列，将结果限制为 10。

```
SELECT * FROM TABLE(
        catalog.system.query(
            query => 'SELECT * FROM customer LIMIT 10;'
        ))
```

以下语句运行相同的查询，但删除了可选的命名参数 `query` 和箭头运算符 `=>`。

```
SELECT * FROM TABLE(
        catalog.system.query(
            'SELECT * FROM customer LIMIT 10;'
        ))
```

为了便于重复使用，也可以将其封装在联合视图中。当与视图结合使用时，必须使用完整的函数解析路径。

```
CREATE VIEW AwsDataCatalog.default.example_view AS
    SELECT * FROM TABLE (
        catalog.system.query('SELECT * FROM customer LIMIT 10;')
    )
```

## 选择退出查询传递
<a name="federated-query-passthrough-sql-based-connectors-opting-out"></a>

要禁用传递查询，请添加名为 `enable_query_passthrough` 的 Lambda 环境变量并将其设置为 `false`。