查询与转换
Databend 通过其 ELT(提取、加载、转换)模型引入了数据处理的创新方法。该模型的一个重要方面是查询阶段文件中的数据。
您可以使用 SELECT
语句查询阶段文件中的数据。此功能适用于以下类型的阶段:
- 用户阶段、内部阶段或外部阶段。
- 在您的对象存储中创建的存储桶或容器,例如 Amazon S3、Google Cloud Storage 和 Microsoft Azure。
- 可通过 HTTPS 访问的远程服务器。
此功能在加载数据之前或之 后检查或查看阶段文件内容时特别有用。
语法和参数
SELECT [<alias>.]<column> [, <column> ...] | [<alias>.]$<col_position> [, $<col_position> ...]
FROM {@<stage_name>[/<path>] [<table_alias>] | '<uri>' [<table_alias>]}
[(
[<connection_parameters>],
[ PATTERN => '<regex_pattern>'],
[ FILE_FORMAT => 'CSV | TSV | NDJSON | PARQUET | ORC | <custom_format_name>'],
[ FILES => ( '<file_name>' [ , '<file_name>' ... ])],
[ CASE_SENSITIVE => true | false ]
)]
当阶段路径包含空格或括号等特殊字符时,您可以将整个路径用单引号括起来,如下面的 SQL 语句所示:
SELECT * FROM 's3://mybucket/dataset(databend)/' ...
SELECT * FROM 's3://mybucket/dataset databend/' ...
FILE_FORMAT
FILE_FORMAT 参数允许您指定文件的格式,可以是以下选项之一:CSV、TSV、NDJSON、PARQUET,或您使用 CREATE FILE FORMAT 命令定义的自定义格式。例如,
CREATE FILE FORMAT my_custom_csv TYPE=CSV FIELD_DELIMITER='\t';
SELECT $1 FROM @my_stage/file (FILE_FORMAT=>'my_custom_csv');
请注意,当您需要从阶段文件查询或执行 COPY INTO 操作时,必须在创建阶段时明确指定文件格式。否则,将应用默认格式 Parquet。请参见以下示例:
CREATE STAGE my_stage FILE_FORMAT = (TYPE = CSV);
在您以不同于指定阶段格式的格式阶段文件的情况下,您可以在 SELECT 或 COPY INTO 语句中明确 指定文件格式。以下是示例:
SELECT $1 FROM @my_stage (FILE_FORMAT=>'NDJSON');
COPY INTO my_table FROM (SELECT $1 SELECT @my_stage t) FILE_FORMAT = (TYPE = NDJSON);
PATTERN
PATTERN 选项允许您指定一个基于 PCRE2 的正则表达式模式,用单引号括起来,以匹配文件名。它用于根据提供的模式过滤和选择文件。例如,您可以使用 '.*parquet' 模式来匹配所有以 "parquet" 结尾的文件名。有关 PCRE2 语法的详细信息,您可以参考 http://www.pcre.org/current/doc/html/pcre2syntax.html 上的文档。
FILES
FILES 选项允许您明确指定一个或多个用逗号分隔的文件名。此选项允许您直接过滤和查询文件夹中特定文件的数据。例如,如果您想从 Parquet 文件 "books-2023.parquet"、"books-2022.parquet" 和 "books-2021.parquet" 中查询数据,您可以在 FILES 选项中提供这些文件名。
CASE_SENSITIVE
CASE_SENSITIVE 参数确定查询的 Parquet 文件中的列名是否区分大小写:
CASE_SENSITIVE => false
(默认):列名不区分大小写,即b
和B
被视为相同。CASE_SENSITIVE => true
:列名区分大小写,即只有完全匹配(包括大小写)才有效。例如,如果文件中的列名为B
,则查询B
将成功,但如果列名为b
,则查询将失败。
例如,如果您在 Parquet 文件中有一个名为 MinTemp
的列,当 CASE_SENSITIVE
设置为 false
时,您可以使用以下任一语句查询它:
SELECT MinTemp FROM '@mystage/weather.parquet'(CASE_SENSITIVE=>false);
SELECT MINTEMP FROM '@mystage/weather.parquet'(CASE_SENSITIVE=>false);
SELECT mintemp FROM '@mystage/weather.parquet'(CASE_SENSITIVE=>false);
当 CASE_SENSITIVE
设置为 true
时,您必须使用文件中显示的完全列名:
SELECT `MinTemp` FROM '@mystage/weather.parquet'(CASE_SENSITIVE=>true);
table_alias
在 SELECT 语句中处理阶段文件时,如果没有可用的表名,您可以为文件分配一个别名。这允许您将文件视为表,其字段作为表中的列。这在 SELECT 语句中处理多个表或选择特定列时非常有用。以下是一个示例:
-- 别名 't1' 表示阶段文件,而 't2' 是一个常规表
SELECT t1.$1, t2.$2 FROM @my_stage t1, t2;
$col_position
在从阶段文件选择时,您可以使用列位置,这些位置从 1 开始。目前,使用列位置从阶段文件进行 SELECT 操作的功能仅限于 Parquet、NDJSON、CSV 和 TSV 格式。
SELECT $2 FROM @my_stage (FILES=>('sample.csv')) ORDER BY $1;
需要注意的是,在处理 NDJSON 时,仅允许 $1,表示整行并具有 Variant 数据类型。要选择特定字段,请使用 $1:<field_name>
。
-- 使用列位置选择整行:
SELECT $1 FROM @my_stage (FILE_FORMAT=>'NDJSON')
-- 使用列位置选择名为 "a" 的特定字段:
SELECT $1:a FROM @my_stage (FILE_FORMAT=>'NDJSON')
在使用 COPY INTO 从阶段文件复制数据时,Databend 将 NDJSON 文件顶层的字段名与目标表中的列名匹配,而不是依赖列位置。在下面的示例中,表 my_table 应具有与 NDJSON 文件顶层字段名相同的列定义:
COPY INTO my_table FROM (SELECT $1 SELECT @my_stage t) FILE_FORMAT = (type = NDJSON)
connection_parameters
要查询存储服务中存储桶或容器中的数据文件,请提供必要的连接参数。有关每个存储服务的可用连接参数,请参阅 连接参数。
uri
指定可通过 HTTPS 访问的远程文件的 URI。
限制
在查询阶段文件时,以下限制适用于特定格式的约束:
- 使用符号 * 选择所有字段仅支持 Parquet 文件。
- 在从 CSV 或 TSV 文件选择时,所有字段都被解析为字符串,并且 SELECT 语句仅允许使用列位置。此外,文件中的字段数量有限制,不得超过 max.N+1000。例如,如果语句是
SELECT $1, $2 FROM @my_stage (FILES=>('sample.csv'))
,则 sample.csv 文件最多可以有 1,002 个字段。