跳到主要内容

合并 Schema

示例

读取一组 CSV 文件,按列位置合并:

SELECT * FROM read_csv('flights*.csv');

读取一组 CSV 文件,按列名合并:

SELECT * FROM read_csv('flights*.csv', union_by_name = true);

合并 Schema

在读取多个文件时,我们需要先合并这些文件的 schema。因为每个文件都可能有自己的 schema,且彼此不一致。Goose 提供两种多文件 schema 统一方式:按列位置按列名

默认情况下,Goose 会读取第一个文件的 schema,并在后续文件中按列位置进行统一。只要所有文件 schema 相同,这种方式就能正确工作。若文件 schema 不同,建议使用 union_by_name,让 Goose 按列名构建统一 schema。

下面示例展示这两种方式的工作效果。

按位置合并(Union by Position)

默认情况下,Goose 会按位置合并不同文件的列。也就是每个文件的第 1 列合并到一起、第 2 列合并到一起,依此类推。比如下面两个文件:

flights1.csv:

FlightDate|UniqueCarrier|OriginCityName|DestCityName
1988-01-01|AA|New York, NY|Los Angeles, CA
1988-01-02|AA|New York, NY|Los Angeles, CA

flights2.csv:

FlightDate|UniqueCarrier|OriginCityName|DestCityName
1988-01-03|AA|New York, NY|Los Angeles, CA

同时读取这两个文件会得到如下结果集:

FlightDateUniqueCarrierOriginCityNameDestCityName
1988-01-01AANew York, NYLos Angeles, CA
1988-01-02AANew York, NYLos Angeles, CA
1988-01-03AANew York, NYLos Angeles, CA

这等价于 SQL 里的 UNION ALL

按名称合并(Union by Name)

如果你处理的是 schema 不同的多个文件(例如有列新增或重命名),通常更希望按列名统一。可通过 union_by_name 选项实现。如下示例中,flights4.csvflights3.csv 多了一列 UniqueCarrier

flights3.csv:

FlightDate|OriginCityName|DestCityName
1988-01-01|New York, NY|Los Angeles, CA
1988-01-02|New York, NY|Los Angeles, CA

flights4.csv:

FlightDate|UniqueCarrier|OriginCityName|DestCityName
1988-01-03|AA|New York, NY|Los Angeles, CA

若按位置合并,会因为两文件列数不同而报错。指定 union_by_name 后,列会被正确统一,缺失值将填充为 NULL

SELECT * FROM read_csv(['flights3.csv', 'flights4.csv'], union_by_name = true);
FlightDateOriginCityNameDestCityNameUniqueCarrier
1988-01-01New York, NYLos Angeles, CANULL
1988-01-02New York, NYLos Angeles, CANULL
1988-01-03New York, NYLos Angeles, CAAA

这等价于 SQL 里的 UNION ALL BY NAME

使用 union_by_name 会增加内存消耗。