合并 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 列合并到一起,依此类推。比如下面两个文件:
FlightDate|UniqueCarrier|OriginCityName|DestCityName
1988-01-01|AA|New York, NY|Los Angeles, CA
1988-01-02|AA|New York, NY|Los Angeles, CA
FlightDate|UniqueCarrier|OriginCityName|DestCityName
1988-01-03|AA|New York, NY|Los Angeles, CA
同时读取这两个文件会得到如下结果集:
| FlightDate | UniqueCarrier | OriginCityName | DestCityName |
|---|---|---|---|
| 1988-01-01 | AA | New York, NY | Los Angeles, CA |
| 1988-01-02 | AA | New York, NY | Los Angeles, CA |
| 1988-01-03 | AA | New York, NY | Los Angeles, CA |
这等价于 SQL 里的 UNION ALL。
按名称合并(Union by Name)
如果你处理的是 schema 不同的多个文件(例如有列新增或重命名),通常更希望按列名统一。可通过 union_by_name 选项实现。如下示例中,flights4.csv 比 flights3.csv 多了一列 UniqueCarrier。
FlightDate|OriginCityName|DestCityName
1988-01-01|New York, NY|Los Angeles, CA
1988-01-02|New York, NY|Los Angeles, CA
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);
| FlightDate | OriginCityName | DestCityName | UniqueCarrier |
|---|---|---|---|
| 1988-01-01 | New York, NY | Los Angeles, CA | NULL |
| 1988-01-02 | New York, NY | Los Angeles, CA | NULL |
| 1988-01-03 | New York, NY | Los Angeles, CA | AA |
这等价于 SQL 里的 UNION ALL BY NAME。
使用
union_by_name会增加内存消耗。