diff --git a/.translation-init b/.translation-init index 612f7ad62e..fc44ec759f 100644 --- a/.translation-init +++ b/.translation-init @@ -1 +1 @@ -Translation initialization: 2025-08-07T09:16:55.714367 +Translation initialization: 2025-08-07T10:37:34.904930 diff --git a/docs/cn/guides/40-load-data/04-transform/00-querying-parquet.md b/docs/cn/guides/40-load-data/04-transform/00-querying-parquet.md index 78858e8945..d86844a1e7 100644 --- a/docs/cn/guides/40-load-data/04-transform/00-querying-parquet.md +++ b/docs/cn/guides/40-load-data/04-transform/00-querying-parquet.md @@ -1,59 +1,39 @@ --- -title: 查询 Stage 中的 Parquet 文件 +title: 查询暂存区中的 Parquet 文件 sidebar_label: Parquet --- -## 查询 Stage 中的 Parquet 文件 -语法: -```sql -SELECT [.] [, ...] -FROM {@[/] [] | '' []} -[( - [], - [ PATTERN => ''], - [ FILE_FORMAT => 'PARQUET | '], - [ FILES => ( '' [ , '' ] [ , ... ] ) ], - [ CASE_SENSITIVE => true | false ] -)] -``` +## 语法: -:::info 提示 -**查询返回内容说明:** - -* **返回格式**: 列值以其原生数据类型返回 (非 variant 类型) -* **访问方式**: 直接使用列名 `column_name` -* **示例**: `SELECT id, name, age FROM @stage_name` -* **关键特性**: - * 无需使用路径表达式 (如 `$1:name`) - * 无需类型转换 - * Parquet 文件包含内嵌的 schema 信息 -::: +- [将行作为 Variant 查询](./index.md#query-rows-as-variants) +- [按名称查询列](./index.md#query-columns-by-name) +- [查询元数据](./index.md#query-metadata) ## 教程 -### 步骤 1. 创建外部 Stage +### 步骤 1:创建外部暂存区(Stage) -使用您自己的 S3 存储桶和凭证创建一个外部 stage,用于存储 Parquet 文件。 +使用您自己的 S3 存储桶和凭据创建一个外部暂存区(Stage),用于存放 Parquet 文件。 ```sql CREATE STAGE parquet_query_stage URL = 's3://load/parquet/' CONNECTION = ( ACCESS_KEY_ID = '' - SECRET_ = '< = '' + SECRET_ACCESS_KEY = '' ); ``` -### 步骤 2. 创建自定义 Parquet 文件格式 +### 步骤 2:创建自定义 Parquet 文件格式 ```sql -CREATE FILE FORMAT parquet_query_format - TYPE = PARQUET - ; +CREATE FILE FORMAT parquet_query_format TYPE = PARQUET; ``` -- 更多 Parquet 文件格式选项请参考 [Parquet 文件格式选项](/sql/sql-reference/file-format-options#parquet-options) +- 更多 Parquet 文件格式选项,请参阅 [Parquet 文件格式选项](/sql/sql-reference/file-format-options#parquet-options) + +### 步骤 3:查询 Parquet 文件 -### 步骤 3. 查询 Parquet 文件 +按列名查询: ```sql SELECT * @@ -63,9 +43,23 @@ FROM @parquet_query_stage PATTERN => '.*[.]parquet' ); ``` -### 包含元数据的查询 -直接从 stage 查询 Parquet 文件,包括 `METADATA$FILENAME` 和 `METADATA$FILE_ROW_NUMBER` 等元数据列: +按路径表达式查询: + + +```sql +SELECT $1 +FROM @parquet_query_stage +( + FILE_FORMAT => 'parquet_query_format', + PATTERN => '.*[.]parquet' +); +``` + + +### 查询元数据(Metadata) + +直接从暂存区(Stage)查询 Parquet 文件,并包含 `METADATA$FILENAME` 和 `METADATA$FILE_ROW_NUMBER` 等元数据(Metadata)列: ```sql SELECT diff --git a/docs/cn/guides/40-load-data/04-transform/01-querying-csv.md b/docs/cn/guides/40-load-data/04-transform/01-querying-csv.md index 60fa3d7379..b4da13e087 100644 --- a/docs/cn/guides/40-load-data/04-transform/01-querying-csv.md +++ b/docs/cn/guides/40-load-data/04-transform/01-querying-csv.md @@ -1,41 +1,18 @@ --- -title: 查询 Stage 中的 CSV 文件 +title: 查询暂存区中的 CSV 文件 sidebar_label: CSV --- -## 查询 Stage 中的 CSV 文件 +## 语法: -语法: -```sql -SELECT [.]$ [, $ ...] -FROM {@[/] [] | '' []} -[( - [], - [ PATTERN => ''], - [ FILE_FORMAT => 'CSV| '], - [ FILES => ( '' [ , '' ] [ , ... ] ) ] -)] -``` - - -:::info 提示 -**查询返回内容说明:** - -* **返回格式**:默认以字符串形式返回各列值 -* **访问方式**:使用位置引用 `$`(例如 `$1`、`$2`、`$3`) -* **示例**:`SELECT $1, $2, $3 FROM @stage_name` -* **关键特性**: - * 通过位置而非列名访问数据 - * 每个 `$` 引用单列而非整行 - * 非字符串操作需类型转换(如 `CAST($1 AS INT)`) - * CSV 文件不包含内嵌模式信息 -::: +- [按位置查询列](./index.md#query-columns-by-position) +- [查询元数据](./index.md#query-metadata) ## 教程 -### 步骤 1. 创建外部 Stage +### 步骤 1:创建外部暂存区 -使用您自己的 S3 存储桶和凭证创建外部 Stage,用于存储 CSV 文件。 +创建一个外部暂存区(Stage),并配置你的 S3 存储桶和凭证,CSV 文件存储在该位置。 ```sql CREATE STAGE csv_query_stage URL = 's3://load/csv/' @@ -45,7 +22,7 @@ CONNECTION = ( ); ``` -### 步骤 2. 创建自定义 CSV 文件格式 +### 步骤 2:创建自定义 CSV 文件格式 ```sql CREATE FILE FORMAT csv_query_format @@ -53,12 +30,12 @@ CREATE FILE FORMAT csv_query_format RECORD_DELIMITER = '\n', FIELD_DELIMITER = ',', COMPRESSION = AUTO, - SKIP_HEADER = 1; -- 如果 CSV 文件包含表头,查询时跳过首行 + SKIP_HEADER = 1; -- 如果 CSV 文件包含表头,查询时跳过第一行 ``` -- 更多 CSV 文件格式选项请参考 [CSV 文件格式选项](/sql/sql-reference/file-format-options#csv-options) +- 更多 CSV 文件格式选项,请参考 [CSV 文件格式选项](/sql/sql-reference/file-format-options#csv-options) -### 步骤 3. 查询 CSV 文件 +### 步骤 3:查询 CSV 文件 ```sql SELECT $1, $2, $3 @@ -69,7 +46,7 @@ FROM @csv_query_stage ); ``` -如果 CSV 文件使用 gzip 压缩,可使用以下查询: +如果 CSV 文件使用 gzip 压缩,我们可以使用以下查询: ```sql SELECT $1, $2, $3 @@ -79,9 +56,9 @@ FROM @csv_query_stage PATTERN => '.*[.]csv[.]gz' ); ``` -### 包含元数据的查询 +### 查询元数据 -直接从 Stage 查询 CSV 文件,包含 `METADATA$FILENAME` 和 `METADATA$FILE_ROW_NUMBER` 等元数据列: +直接从暂存区(Stage)查询 CSV 文件,包括 `METADATA$FILENAME` 和 `METADATA$FILE_ROW_NUMBER` 等元数据列: ```sql SELECT diff --git a/docs/cn/guides/40-load-data/04-transform/02-querying-tsv.md b/docs/cn/guides/40-load-data/04-transform/02-querying-tsv.md index 656afa0b25..9972e30be3 100644 --- a/docs/cn/guides/40-load-data/04-transform/02-querying-tsv.md +++ b/docs/cn/guides/40-load-data/04-transform/02-querying-tsv.md @@ -1,41 +1,19 @@ --- -title: 查询 Stage 中的 TSV 文件 +title: 查询暂存区中的 TSV 文件 sidebar_label: TSV --- -## 查询 Stage 中的 TSV 文件 - -语法: -```sql -SELECT [.]$ [, $ ...] -FROM {@[/] [] | '' []} -[( - [], - [ PATTERN => ''], - [ FILE_FORMAT => 'TSV| '], - [ FILES => ( '' [ , '' ] [ , ... ] ) ] -)] -``` +## 语法: +- [按位置查询列](./index.md#query-columns-by-position) +- [查询元数据](./index.md#query-metadata) -:::info 提示 -**查询返回内容说明:** - -* **返回格式**:默认以字符串形式返回各列值 -* **访问方式**:使用位置引用 `$` (例如 `$1`, `$2`, `$3`) -* **示例**:`SELECT $1, $2, $3 FROM @stage_name` -* **关键特性**: - * 通过位置而非列名访问数据 - * 每个 `$` 对应单个列而非整行 - * 非字符串操作需类型转换 (例如 `CAST($1 AS INT)`) - * TSV 文件中不包含内嵌的 schema 信息 -::: ## 教程 -### 第一步:创建外部 Stage +### 步骤 1:创建外部暂存区 -使用您的 S3 存储桶和凭证创建外部 stage,用于存储 TSV 文件。 +使用您自己的 S3 存储桶和凭据创建一个外部暂存区(Stage),其中存放了您的 TSV 文件。 ```sql CREATE STAGE tsv_query_stage URL = 's3://load/tsv/' @@ -45,7 +23,7 @@ CONNECTION = ( ); ``` -### 第二步:创建自定义 TSV 文件格式 +### 步骤 2:创建自定义 TSV 文件格式 ```sql CREATE FILE FORMAT tsv_query_format @@ -55,9 +33,9 @@ CREATE FILE FORMAT tsv_query_format COMPRESSION = AUTO; ``` -- 更多 TSV 文件格式选项请参考 [TSV 文件格式选项](/sql/sql-reference/file-format-options#tsv-options) +- 更多 TSV 文件格式选项,请参阅 [TSV 文件格式选项](/sql/sql-reference/file-format-options#tsv-options) -### 第三步:查询 TSV 文件 +### 步骤 3:查询 TSV 文件 ```sql SELECT $1, $2, $3 @@ -78,10 +56,9 @@ FROM @tsv_query_stage PATTERN => '.*[.]tsv[.]gz' ); ``` +### 查询元数据 -### 查询包含元数据 - -直接从 stage 查询 TSV 文件,包括 `METADATA$FILENAME` 和 `METADATA$FILE_ROW_NUMBER` 等元数据列: +直接从暂存区(Stage)查询 TSV 文件,并包含 `METADATA$FILENAME` 和 `METADATA$FILE_ROW_NUMBER` 等元数据列: ```sql SELECT diff --git a/docs/cn/guides/40-load-data/04-transform/03-querying-ndjson.md b/docs/cn/guides/40-load-data/04-transform/03-querying-ndjson.md index 8f6d020ab4..3cd4127399 100644 --- a/docs/cn/guides/40-load-data/04-transform/03-querying-ndjson.md +++ b/docs/cn/guides/40-load-data/04-transform/03-querying-ndjson.md @@ -1,9 +1,9 @@ --- -title: 查询暂存区中的 NDJSON 文件 +title: 查询暂存区(Stage)中的 NDJSON 文件 sidebar_label: NDJSON --- -在 Databend 中,你可以直接查询存储在暂存区(Stage)中的 NDJSON 文件,而无需先将数据加载到表中。这种方法对于数据探索、ETL 处理和即席分析等场景特别有用。 +在 Databend 中,你可以直接查询存储在暂存区(Stage)中的 NDJSON 文件,而无需先将数据加载到表中。这种方法对于数据探索、ETL 处理和即席分析场景特别有用。 ## 什么是 NDJSON? @@ -21,39 +21,16 @@ NDJSON(Newline Delimited JSON,换行符分隔的 JSON)是一种基于 JSON - **兼容大数据**:广泛用于日志文件、数据导出和 ETL Pipeline。 - **易于处理**:每一行都是一个独立的 JSON 对象,支持并行处理。 -## 查询暂存区中的 NDJSON 文件 +## 语法 -语法: -```sql -SELECT [.]$1: [, $1: ...] -FROM {@[/] [] | '' []} -[( - [], - [ PATTERN => ''], - [ FILE_FORMAT => 'NDJSON| '], - [ FILES => ( '' [ , '' ] [ , ... ] ) ] -)] -``` - - -:::info 提示 -**查询返回内容说明:** - -* **返回格式**:每一行作为一个单独的 VARIANT 对象(通过 `$1` 引用)。 -* **访问方法**:使用路径表达式 `$1:column_name`。 -* **示例**:`SELECT $1:title, $1:author FROM @stage_name`。 -* **主要特性**: - * 必须使用路径表示法来访问特定字段。 - * 对于特定类型的操作,需要进行类型转换(例如,`CAST($1:id AS INT)`)。 - * 每一行 NDJSON 都被解析为一个完整的 JSON 对象。 - * 整行数据表示为一个单独的 VARIANT 对象。 -::: +- [将行作为 Variant 查询](./index.md#query-rows-as-variants) +- [查询元数据](./index.md#query-metadata) ## 教程 -### 步骤 1. 创建外部暂存区 +### 步骤 1. 创建外部暂存区(Stage) -使用你自己的 S3 存储桶和凭证创建一个外部暂存区,你的 NDJSON 文件存储在该位置。 +使用你自己的 S3 存储桶和凭据创建一个外部暂存区(Stage),你的 NDJSON 文件存储在该位置。 ```sql CREATE STAGE ndjson_query_stage URL = 's3://load/ndjson/' @@ -75,7 +52,7 @@ CREATE FILE FORMAT ndjson_query_format ### 步骤 3. 查询 NDJSON 文件 -现在你可以直接从暂存区查询 NDJSON 文件。此示例从每个 JSON 对象中提取 `title` 和 `author` 字段: +现在,你可以直接从暂存区(Stage)查询 NDJSON 文件。此示例从每个 JSON 对象中提取 `title` 和 `author` 字段: ```sql SELECT $1:title, $1:author @@ -87,10 +64,10 @@ FROM @ndjson_query_stage ``` **说明:** -- `$1:title` 和 `$1:author`:从 JSON 对象中提取特定字段。`$1` 代表整个 JSON 对象(作为一个 VARIANT),`:字段名` 用于访问单个字段。 -- `@ndjson_query_stage`:引用在步骤 1 中创建的外部暂存区。 +- `$1:title` 和 `$1:author`:从 JSON 对象中提取特定字段。`$1` 代表整个 JSON 对象(作为 Variant 类型),`:field_name` 用于访问单个字段。 +- `@ndjson_query_stage`:引用在步骤 1 中创建的外部暂存区(Stage)。 - `FILE_FORMAT => 'ndjson_query_format'`:使用在步骤 2 中定义的自定义文件格式。 -- `PATTERN => '.*[.]ndjson'`:匹配所有以 `.ndjson` 结尾的文件的正则表达式模式。 +- `PATTERN => '.*[.]ndjson'`:匹配所有以 `.ndjson` 结尾的文件的正则表达式(Regex)模式。 ### 查询压缩文件 @@ -106,34 +83,9 @@ FROM @ndjson_query_stage ``` **主要区别:** 模式 `.*[.]ndjson[.]gz` 匹配以 `.ndjson.gz` 结尾的文件。由于文件格式中设置了 `COMPRESSION = AUTO`,Databend 会在查询执行期间自动解压 gzip 文件。 -### 带元数据查询 - -你还可以在查询中包含文件元数据,这对于跟踪数据血缘和调试非常有用: - -```sql -SELECT - METADATA$FILENAME, - METADATA$FILE_ROW_NUMBER, - $1:title, $1:author -FROM @ndjson_query_stage -( - FILE_FORMAT => 'ndjson_query_format', - PATTERN => '.*[.]ndjson' -); -``` - -**元数据列说明:** -- `METADATA$FILENAME`:显示每行数据来自哪个文件——在查询多个文件时非常有用。 -- `METADATA$FILE_ROW_NUMBER`:显示源文件中的行号——有助于跟踪特定记录。 - -**使用场景:** -- **数据血缘**:跟踪每条记录来自哪个源文件。 -- **调试**:通过文件和行号识别有问题的记录。 -- **增量处理**:只处理特定的文件或文件中的特定范围。 ## 相关文档 - [加载 NDJSON 文件](../03-load-semistructured/03-load-ndjson.md) - 如何将 NDJSON 数据加载到表中 - [NDJSON 文件格式选项](/sql/sql-reference/file-format-options#ndjson-options) - 完整的 NDJSON 格式配置 -- [CREATE STAGE](/sql/sql-commands/ddl/stage/ddl-create-stage) - 管理外部和内部暂存区 -- [查询元数据](./04-querying-metadata.md) - 关于元数据列的更多详细信息 \ No newline at end of file +- [CREATE STAGE](/sql/sql-commands/ddl/stage/ddl-create-stage) - 管理外部和内部暂存区(Stage) \ No newline at end of file diff --git a/docs/cn/guides/40-load-data/04-transform/04-querying-avro.md b/docs/cn/guides/40-load-data/04-transform/04-querying-avro.md index d089a74b9c..19e2bfd6b6 100644 --- a/docs/cn/guides/40-load-data/04-transform/04-querying-avro.md +++ b/docs/cn/guides/40-load-data/04-transform/04-querying-avro.md @@ -1,50 +1,28 @@ --- -title: 查询 Stage 中的 Avro 文件 +title: 查询暂存区中的 Avro 文件 sidebar_label: Avro --- -## 查询 Stage 中的 Avro 文件 +## 语法: -语法: -```sql -SELECT [.]$1: [, $1: ...] -FROM {@[/] [] | '' []} -[( - [], - [ PATTERN => ''], - [ FILE_FORMAT => 'AVRO'], - [ FILES => ( '' [ , '' ] [ , ... ] ) ] -)] -``` - -:::info 提示 -**查询返回内容说明:** - -* **返回格式**:每行作为单个 variant 对象 (引用为 `$1`) -* **访问方法**:使用路径表达式 `$1:column_name` -* **示例**:`SELECT $1:id, $1:name FROM @stage_name` -* **关键特性**: - * 必须使用路径表示法访问特定字段 - * 类型转换需用于特定类型操作 (例如 `CAST($1:id AS INT)`) - * Avro 模式映射为 variant 结构 - * 整行表示为单个 variant 对象 -::: +- [将行作为 Variant 查询](./index.md#query-rows-as-variants) +- [查询元数据](./index.md#query-metadata) ## Avro 查询功能概述 -Databend 提供对直接从 stage 查询 Avro 文件的全面支持,无需先将数据加载到表中即可实现灵活的数据探索和转换。 +Databend 全面支持直接从暂存区(Stage)查询 Avro 文件,无需先将数据加载到表中,即可灵活地进行数据探索与转换。 -* **Variant 表示**:Avro 文件中的每行被视为一个 variant,通过 `$1` 引用,可灵活访问 Avro 数据中的嵌套结构。 -* **类型映射**:每个 Avro 类型映射到 Databend 中对应的 variant 类型。 -* **元数据访问**:可访问 `METADATA$FILENAME` 和 `METADATA$FILE_ROW_NUMBER` 等元数据列,获取有关源文件和行的额外上下文。 +* **Variant 表示**:Avro 文件中的每一行都被视为一个 Variant(Variant),通过 `$1` 引用,可灵活访问 Avro 数据中的嵌套结构。 +* **类型映射**:每个 Avro 类型都会映射到 Databend 中对应的 Variant 类型。 +* **元数据访问**:可访问 `METADATA$FILENAME` 和 `METADATA$FILE_ROW_NUMBER` 等元数据列,获取源文件及行的额外上下文信息。 ## 教程 -本教程演示如何查询存储在 stage 中的 Avro 文件。 +本教程演示如何查询存储在暂存区中的 Avro 文件。 -### 步骤 1. 准备 Avro 文件 +### 第 1 步:准备 Avro 文件 -考虑一个名为 `user` 的 Avro 文件,其模式如下: +假设有一个名为 `user` 的 Avro 文件,其模式如下: ```json { @@ -63,9 +41,9 @@ Databend 提供对直接从 stage 查询 Avro 文件的全面支持,无需先 } ``` -### 步骤 2. 创建外部 Stage +### 第 2 步:创建外部暂存区 -创建一个外部 stage,使用您自己的 S3 存储桶和凭证,其中存储了您的 Avro 文件。 +使用你自己的 S3 存储桶和凭据创建外部暂存区(External Stage),用于存放 Avro 文件。 ```sql CREATE STAGE avro_query_stage @@ -76,11 +54,11 @@ CONNECTION = ( ); ``` -### 步骤 3. 查询 Avro 文件 +### 第 3 步:查询 Avro 文件 #### 基础查询 -直接从 stage 查询 Avro 文件: +直接从暂存区查询 Avro 文件: ```sql SELECT @@ -93,9 +71,9 @@ FROM @avro_query_stage ); ``` -### 包含元数据的查询 +### 带元数据的查询 -直接从 stage 查询 Avro 文件,包括 `METADATA$FILENAME` 和 `METADATA$FILE_ROW_NUMBER` 等元数据列: +直接从暂存区查询 Avro 文件,并包含 `METADATA$FILENAME` 和 `METADATA$FILE_ROW_NUMBER` 等元数据列: ```sql SELECT @@ -112,8 +90,8 @@ FROM @avro_query_stage ## 类型映射到 Variant -Databend 中的 variant 以 JSONB 格式存储。虽然大多数 Avro 类型可直接映射,但需注意以下特殊情况: +Databend 中的 Variant 以 JSONB 形式存储。大多数 Avro 类型可直接映射,但需注意以下特殊情况: -* **时间类型**:`TimeMillis` 和 `TimeMicros` 映射为 `INT64`,因为 JSONB 没有原生 Time 类型。处理这些值时用户应了解原始类型。 -* **Decimal 类型**:Decimal 加载为 `DECIMAL128` 或 `DECIMAL256`。如果精度超过支持限制,可能会报错。 -* **枚举类型**:Avro `ENUM` 类型映射为 Databend 中的 `STRING` 值。 \ No newline at end of file +* **时间类型**:`TimeMillis` 和 `TimeMicros` 映射为 `INT64`,因为 JSONB 没有原生时间类型;处理这些值时请注意其原始类型。 +* **Decimal 类型**:Decimal 加载为 `DECIMAL128` 或 `DECIMAL256`;若精度超出支持范围,将报错。 +* **Enum 类型**:Avro `ENUM` 类型在 Databend 中映射为 `STRING` 值。 \ No newline at end of file diff --git a/docs/cn/guides/40-load-data/04-transform/05-querying-orc.md b/docs/cn/guides/40-load-data/04-transform/05-querying-orc.md new file mode 100644 index 0000000000..56f5a7c55c --- /dev/null +++ b/docs/cn/guides/40-load-data/04-transform/05-querying-orc.md @@ -0,0 +1,109 @@ +--- +title: 查询暂存区(Stage)中的 ORC 文件 +sidebar_label: ORC +--- + +import StepsWrap from '@site/src/components/StepsWrap'; +import StepContent from '@site/src/components/Steps/step-content'; + +## 语法 + +- [将行作为 Variant 查询](./index.md#query-rows-as-variants) +- [按名称查询列](./index.md#query-columns-by-name) +- [查询元数据](./index.md#query-metadata) + +## 教程 + +在本教程中,我们将带你完成以下步骤:下载 ORC 格式的 Iris 数据集、将其上传到 Amazon S3 存储桶、创建外部暂存区(Stage),并直接从 ORC 文件查询数据。 + + + + +### 下载 Iris 数据集 + +从 https://github.com/tensorflow/io/raw/master/tests/test_orc/iris.orc 下载 iris 数据集,然后上传到你的 Amazon S3 存储桶。 + +iris 数据集包含 3 个类别,每个类别 50 条记录,每个类别对应一种鸢尾花。数据集共有 4 个属性:(1)花萼长度,(2)花萼宽度,(3)花瓣长度,(4)花瓣宽度;最后一列为类别标签。 + + + + +### 创建外部暂存区(Stage) + +使用存放 iris 数据集文件的 Amazon S3 存储桶创建外部暂存区(Stage)。 + +```sql +CREATE STAGE orc_query_stage + URL = 's3://databend-doc' + CONNECTION = ( + ACCESS_KEY_ID = '', + SECRET_ACCESS_KEY = '' + ); +``` + + + + +### 查询 ORC 文件 + +按列查询: + +```sql +SELECT * +FROM @orc_query_stage +( + FILE_FORMAT => 'orc', + PATTERN => '.*[.]orc' +); + +┌──────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ sepal_length │ sepal_width │ petal_length │ petal_width │ species │ +├───────────────────┼───────────────────┼───────────────────┼───────────────────┼──────────────────┤ +│ 5.1 │ 3.5 │ 1.4 │ 0.2 │ setosa │ +│ · │ · │ · │ · │ · │ +│ 5.9 │ 3 │ 5.1 │ 1.8 │ virginica │ +└──────────────────────────────────────────────────────────────────────────────────────────────────┘ +``` + +使用路径表达式查询: + +```sql +SELECT $1 +FROM @orc_query_stage +( + FILE_FORMAT => 'orc', + PATTERN => '.*[.]orc' + +); +``` + +你也可以直接查询远程 ORC 文件: + +```sql +SELECT + * +FROM + 'https://github.com/tensorflow/io/raw/master/tests/test_orc/iris.orc' (file_format => 'orc'); +``` + + + + +### 查询元数据 + +直接从暂存区(Stage)查询 ORC 文件,并包含 `METADATA$FILENAME` 和 `METADATA$FILE_ROW_NUMBER` 等元数据列: + +```sql +SELECT + METADATA$FILENAME, + METADATA$FILE_ROW_NUMBER, + * +FROM @orc_query_stage +( + FILE_FORMAT => 'orc', + PATTERN => '.*[.]orc' +); +``` + + + \ No newline at end of file diff --git a/docs/cn/guides/40-load-data/04-transform/06-data-load-transform.md b/docs/cn/guides/40-load-data/04-transform/06-data-load-transform.md new file mode 100644 index 0000000000..1f3e85aae3 --- /dev/null +++ b/docs/cn/guides/40-load-data/04-transform/06-data-load-transform.md @@ -0,0 +1,250 @@ +--- +title: 在加载时转换数据 +--- + +Databend 的 `COPY INTO` 命令允许在数据加载过程中进行数据转换。通过整合基础转换操作,可简化 ETL 流程,无需使用临时表。 + +语法请参见 [查询与转换](./index.md)。 + +可执行的关键转换操作包括: + +- **加载部分数据列**:选择性地导入特定列。 +- **重排列**:在加载过程中更改列顺序。 +- **转换数据类型**:确保数据一致性与兼容性。 +- **执行算术运算**:生成新的派生数据。 +- **将数据加载到包含额外列的表**:将数据映射并插入现有结构。 + +## 教程 + +以下教程演示如何在加载过程中进行数据转换。每个示例均展示从暂存文件加载数据。 + +### 准备工作 + +创建 Stage 并生成示例 Parquet 文件: + +```sql +CREATE STAGE my_parquet_stage; +COPY INTO @my_parquet_stage +FROM ( + SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS id, + 'Name_' || CAST(number AS VARCHAR) AS name, + 20 + MOD(number, 23) AS age, + DATE_ADD('day', MOD(number, 60), '2022-01-01') AS onboarded + FROM numbers(10) +) +FILE_FORMAT = (TYPE = PARQUET); +``` + +查询暂存的示例文件: + +```sql +SELECT * FROM @my_parquet_stage; +``` + +结果: + +``` +┌───────────────────────────────────────┐ +│ id │ name │ age │ onboarded │ +├────────┼────────┼────────┼────────────┤ +│ 1 │ Name_0 │ 20 │ 2022-01-01 │ +│ 2 │ Name_5 │ 25 │ 2022-01-06 │ +│ 3 │ Name_1 │ 21 │ 2022-01-02 │ +│ 4 │ Name_6 │ 26 │ 2022-01-07 │ +│ 5 │ Name_7 │ 27 │ 2022-01-08 │ +│ 6 │ Name_2 │ 22 │ 2022-01-03 │ +│ 7 │ Name_8 │ 28 │ 2022-01-09 │ +│ 8 │ Name_3 │ 23 │ 2022-01-04 │ +│ 9 │ Name_4 │ 24 │ 2022-01-05 │ +│ 10 │ Name_9 │ 29 │ 2022-01-10 │ +└───────────────────────────────────────┘ +``` + +### 教程 1 - 加载部分数据列 + +将数据加载到列数少于源文件的表(例如排除 'age' 列)。 + +```sql +CREATE TABLE employees_no_age ( + id INT, + name VARCHAR, + onboarded timestamp +); + +COPY INTO employees_no_age +FROM ( + SELECT t.id, + t.name, + t.onboarded + FROM @my_parquet_stage t +) +FILE_FORMAT = (TYPE = PARQUET) +PATTERN = '.*parquet'; + +SELECT * FROM employees_no_age; +``` + +结果(前 3 行): + +``` +┌──────────────────────────────────────────────────────────┐ +│ id │ name │ onboarded │ +├─────────────────┼──────────────────┼─────────────────────┤ +│ 1 │ Name_0 │ 2022-01-01 00:00:00 │ +│ 2 │ Name_5 │ 2022-01-06 00:00:00 │ +│ 3 │ Name_1 │ 2022-01-02 00:00:00 │ +└──────────────────────────────────────────────────────────┘ +``` + +### 教程 2 - 加载时重排列 + +将数据加载到列顺序不同的表(例如 'age' 在 'name' 之前)。 + +```sql +CREATE TABLE employees_new_order ( + id INT, + age INT, + name VARCHAR, + onboarded timestamp +); + +COPY INTO employees_new_order +FROM ( + SELECT + t.id, + t.age, + t.name, + t.onboarded + FROM @my_parquet_stage t +) +FILE_FORMAT = (TYPE = PARQUET) +PATTERN = '.*parquet'; + +SELECT * FROM employees_new_order; +``` +结果(前 3 行): + +``` +┌────────────────────────────────────────────────────────────────────────────┐ +│ id │ age │ name │ onboarded │ +├─────────────────┼─────────────────┼──────────────────┼─────────────────────┤ +│ 1 │ 20 │ Name_0 │ 2022-01-01 00:00:00 │ +│ 2 │ 25 │ Name_5 │ 2022-01-06 00:00:00 │ +│ 3 │ 21 │ Name_1 │ 2022-01-02 00:00:00 │ +└────────────────────────────────────────────────────────────────────────────┘ +``` + +### 教程 3 - 加载时转换数据类型 + +加载数据并转换列的数据类型(例如将 'onboarded' 转换为 `DATE`)。 + +```sql +CREATE TABLE employees_date ( + id INT, + name VARCHAR, + age INT, + onboarded date +); + +COPY INTO employees_date +FROM ( + SELECT + t.id, + t.name, + t.age, + to_date(t.onboarded) + FROM @my_parquet_stage t +) +FILE_FORMAT = (TYPE = PARQUET) +PATTERN = '.*parquet'; + +SELECT * FROM employees_date; +``` +结果(前 3 行): + +``` +┌───────────────────────────────────────────────────────────────────────┐ +│ id │ name │ age │ onboarded │ +├─────────────────┼──────────────────┼─────────────────┼────────────────┤ +│ 1 │ Name_0 │ 20 │ 2022-01-01 │ +│ 2 │ Name_5 │ 25 │ 2022-01-06 │ +│ 3 │ Name_1 │ 21 │ 2022-01-02 │ +└───────────────────────────────────────────────────────────────────────┘ +``` + +### 教程 4 - 加载时执行算术运算 + +加载数据并执行算术运算(例如将 'age' 加 1)。 + +```sql +CREATE TABLE employees_new_age ( + id INT, + name VARCHAR, + age INT, + onboarded timestamp +); + +COPY INTO employees_new_age +FROM ( + SELECT + t.id, + t.name, + t.age + 1, + t.onboarded + FROM @my_parquet_stage t +) +FILE_FORMAT = (TYPE = PARQUET) +PATTERN = '.*parquet'; + +SELECT * FROM employees_new_age; +``` +结果(前 3 行): + +``` +┌────────────────────────────────────────────────────────────────────────────┐ +│ id │ name │ age │ onboarded │ +├─────────────────┼──────────────────┼─────────────────┼─────────────────────┤ +│ 1 │ Name_0 │ 21 │ 2022-01-01 00:00:00 │ +│ 2 │ Name_5 │ 26 │ 2022-01-06 00:00:00 │ +│ 3 │ Name_1 │ 22 │ 2022-01-02 00:00:00 │ +└────────────────────────────────────────────────────────────────────────────┘ +``` + +### 教程 5 - 加载到包含额外列的表 + +将数据加载到列数多于源文件的表。 + +```sql +CREATE TABLE employees_plus ( + id INT, + name VARCHAR, + age INT, + onboarded timestamp, + lastday timestamp +); + +COPY INTO employees_plus (id, name, age, onboarded) +FROM ( + SELECT + t.id, + t.name, + t.age, + t.onboarded + FROM @my_parquet_stage t +) +FILE_FORMAT = (TYPE = PARQUET) +PATTERN = '.*parquet'; + +SELECT * FROM employees_plus; +``` +结果(前 3 行): + +``` +┌──────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ id │ name │ age │ onboarded │ lastday │ +├─────────────────┼──────────────────┼─────────────────┼─────────────────────┼─────────────────────┤ +│ 1 │ Name_0 │ 20 │ 2022-01-01 00:00:00 │ NULL │ +│ 2 │ Name_5 │ 25 │ 2022-01-06 00:00:00 │ NULL │ +│ 3 │ Name_1 │ 21 │ 2022-01-02 00:00:00 │ NULL │ +└──────────────────────────────────────────────────────────────────────────────────────────────────┘ +``` \ No newline at end of file diff --git a/docs/cn/guides/40-load-data/04-transform/index.md b/docs/cn/guides/40-load-data/04-transform/index.md index 2c78c07950..6458b1ab2f 100644 --- a/docs/cn/guides/40-load-data/04-transform/index.md +++ b/docs/cn/guides/40-load-data/04-transform/index.md @@ -3,44 +3,154 @@ title: 查询与转换 slug: querying-stage --- -Databend 允许直接查询暂存文件而无需先将数据加载到表中。可以从任何类型的 stage(用户、内部、外部)或直接从对象存储和 HTTPS URL 查询文件。非常适合在数据加载前后进行检查、验证和转换。 +Databend 支持直接查询暂存文件,无需先将数据加载到表中。可以从任何类型的暂存区(用户暂存区、内部暂存区、外部暂存区)查询文件,或直接从对象存储和 HTTPS URL 查询。这非常适合在加载数据之前或之后进行数据检查、验证和转换。 ## 语法 +仅查询 + +```sql +SELECT { + [.] [, [.] ...] -- 按名称查询列 + | [.]$ [, [.]$ ...] -- 按位置查询列 + | [.]$1[:] [, [.]$1[:] ...] -- 将行作为 Variant 查询 +} +FROM {@[/] | ''} -- 暂存区表函数 + [( -- 暂存区表函数参数 + [], + [ PATTERN => ''], + [ FILE_FORMAT => 'CSV | TSV | NDJSON | PARQUET | ORC | Avro | '], + [ FILES => ( '' [ , '' ... ])], + [ CASE_SENSITIVE => true | false ] + )] + [] +``` + +带转换的复制 + ```sql -SELECT [.] [, ...] | [.]$ [, $ ...] -FROM {@[/] [] | '' []} -[( - [], - [ PATTERN => ''], - [ FILE_FORMAT => 'CSV | TSV | NDJSON | PARQUET | ORC | Avro | '], - [ FILES => ( '' [ , '' ... ])], - [ CASE_SENSITIVE => true | false ] -)] +COPY INTO [.] [ ( [ , ... ] ) ] + FROM ( + SELECT { + [.] [, [.] ...] -- 按名称查询列 + | [.]$ [, [.]$ ...] -- 按位置查询列 + | [.]$1[:] [, [.]$1[:] ...] -- 将行作为 Variant 查询 + } ] + FROM {@[/] | ''} + ) +[ FILES = ( '' [ , '' ] [ , ... ] ) ] +[ PATTERN = '' ] +[ FILE_FORMAT = ( + FORMAT_NAME = '' + | TYPE = { CSV | TSV | NDJSON | PARQUET | ORC | AVRO } [ formatTypeOptions ] + ) ] +[ copyOptions ] ``` +:::info 注意 + +对比两种语法 +- 相同的 `Select List` +- 相同的 ` FROM {@[/] | ''}` +- 不同的参数: + - 查询使用 `表函数参数`,即 `( => , ...)` + - 转换在 [Copy into table](/sql/sql-commands/dml/dml-copy-into-table) 的末尾使用选项 -## 参数概览 +::: -控制数据访问和解析的关键参数: + +## FROM 子句 + +FROM 子句使用与 `表函数` 类似的语法。与普通表一样,当与其他表连接时,可以使用表 `别名`。 + +表函数参数: | 参数 | 描述 | -| --------- | ----------- | +|-------------------------|---------------------------------------------------------| | `FILE_FORMAT` | 文件格式类型 (CSV, TSV, NDJSON, PARQUET, ORC, Avro) | | `PATTERN` | 用于筛选文件的正则表达式模式 | -| `FILES` | 要查询的显式文件列表 | -| `CASE_SENSITIVE` | 列名大小写敏感性 (Parquet) | -| `table_alias` | 引用暂存文件的别名 | -| `$col_position` | 按位置选择列 (从1开始) | +| `FILES` | 要查询的文件的显式列表 | +| `CASE_SENSITIVE` | 列名大小写敏感(仅限 Parquet) | | `connection_parameters` | 外部存储连接详情 | -| `uri` | 远程文件的 URI | - -## 支持的文件格式 - -| 文件格式 | 返回格式 | 访问方法 | 示例 | 指南 | -| ----------- | ------------ | ------------- | ------- |-------------------------------------------| -| Parquet | 原生数据类型 | 直接列名 | `SELECT id, name FROM` | [查询 Parquet 文件](./00-querying-parquet.md) | -| ORC | 原生数据类型 | 直接列名 | `SELECT id, name FROM` | [查询 ORC 文件](./05-querying-orc.md) | -| CSV | 字符串值 | 位置引用 `$` | `SELECT $1, $2 FROM` | [查询 CSV 文件](./01-querying-csv.md) | -| TSV | 字符串值 | 位置引用 `$` | `SELECT $1, $2 FROM` | [查询 TSV 文件](./02-querying-tsv.md) | -| NDJSON | Variant 对象 | 路径表达式 `$1:` | `SELECT $1:id, $1:name FROM` | [查询 NDJSON 文件](./03-querying-ndjson.md) | -| Avro | Variant 对象 | 路径表达式 `$1:` | `SELECT $1:id, $1:name FROM` | [查询 Avro 文件](./04-querying-avro.md) | \ No newline at end of file + +## 查询文件数据 + +select 列表支持三种语法;只能使用其中一种,不能混合使用。 + +### 将行作为 Variant 查询 + +- 支持的文件格式:NDJSON, AVRO, Parquet, ORC + +:::info 注意 + +目前对于 Parquet 和 ORC,`将行作为 Variant 查询` 比 `按名称查询列` 慢,并且这两种方法不能混合使用。 + +::: + +语法: + +```sql +SELECT [.]$1[:] [, [.]$1[:] ...] +``` + +- 示例:`SELECT $1:id, $1:name FROM ...` +- 表结构:($1: Variant)。即,具有 Variant 对象类型的单列,每个 Variant 代表一整行 +- 注意: + - 像 `$1:column` 这样的路径表达式的类型也是 Variant,当在表达式中使用或加载到目标表列时,它可以自动转换为原生类型。有时你可能希望在进行特定类型操作之前手动转换(例如,`CAST($1:id AS INT)`),以使语义更明确。 + + +### 按名称查询列 +- 支持的文件格式:NDJSON, AVRO, Parquet, ORC + +```sql +SELECT [.] [, [.] ...] +``` + +- 示例:`SELECT id, name FROM ...` +- 表结构:从 Parquet 或 ORC 文件模式映射的列 +- 注意: + - 所有文件都要求具有相同的 Parquet/ORC 模式;否则,将返回错误 + + +### 按位置查询列 +- 支持的文件格式:CSV, TSV + +```sql +SELECT [.]$[, [.]$, ...] +``` +- 示例:`SELECT $1, $2 FROM ...` +- 表结构:类型为 `VARCHAR NULL` 的列 +- 注意 + - `` 从 1 开始 + +## 查询元数据 + +你还可以在查询中包含文件元数据,这对于跟踪数据血缘和调试非常有用: + +```sql +SELECT METADATA$FILENAME, METADATA$FILE_ROW_NUMBER, $1, +( + FILE_FORMAT => 'ndjson_query_format', + PATTERN => '.*[.]ndjson' +); +``` + +对于支持的文件格式,可以使用以下文件级元数据字段: + +| 文件元数据 | 类型 | 描述 | +| -------------------------- | ------- |--------------------------------------------------| +| `METADATA$FILENAME` | VARCHAR | 读取行的文件路径 | +| `METADATA$FILE_ROW_NUMBER` | INT | 文件内的行号(从 0 开始) | + + +**使用场景:** +- **数据血缘**:跟踪每个记录来自哪个源文件 +- **调试**:按文件和行号识别有问题的记录 +- **增量处理**:仅处理特定文件或文件内的范围 + +## 按文件格式分类的教程 +- [查询 Parquet 文件](./00-querying-parquet.md) +- [查询 ORC 文件](./05-querying-orc.md) +- [查询 NDJSON 文件](./03-querying-ndjson.md) +- [查询 Avro 文件](./04-querying-avro.md) +- [查询 CSV 文件](./01-querying-csv.md) +- [查询 TSV 文件](./02-querying-tsv.md) \ No newline at end of file