在DuckdDB中利用glob()和文件重定向实现对多个xlsx文件按列名合并

假定存在如下电子表格

D from read_sheet('n1.et');
┌───────┬───────┐
│  C1   │  C2   │
│ int64 │ int64 │
├───────┼───────┤
│   1   │   2   │
└───────┴───────┘
D from read_sheet('n2.et');
┌───────┬───────┐
│  C1   │  C3   │
│ int64 │ int64 │
├───────┼───────┤
│   1   │   3   │
└───────┴───────┘

希望两个文件合并后显示如下,即同名的列显示在一列,如果某个列在某个文件中不存在,则显示NULL,这在DuckdDB中称作union by name。

D from read_sheet('n1.et') union by name from read_sheet('n2.et');
┌───────┬───────┬───────┐
│  C1   │  C2   │  C3   │
│ int64 │ int64 │ int64 │
├───────┼───────┼───────┤
│     1 │     2 │  NULL │
│     1 │  NULL │     3 │
└───────┴───────┴───────┘

现在rusty_sheet插件尚不支持多个xlsx文件自动union by name,所以要手工编写SQL,如果文件很多,复制粘贴很乏味也容易出错,能否用SQL编程实现。
其实可以,如下的SQL就可以实现输出上述union by name的SQL。

D select 'from read_sheet('''||file||case when row_number()over()<> count()over()then ''') union by name' else ''');' end as " " from glob('n*.et');
┌────────────────────────────────────────┐
│                                        │
│                varchar                 │
├────────────────────────────────────────┤
│ from read_sheet('n1.et') union by name │
│ from read_sheet('n2.et');              │
└────────────────────────────────────────┘

但是要把SQL语句从输出中复制粘贴执行仍然很乏味也容易出错。
方法1
使用.output将结果重定向到脚本文件,然后执行此文件

load '/par/rusty_sheet.duckdb_extension';
.header off
.mode list
.output script.sql
select 'from read_sheet('''||file||case when row_number()over()<> count()over()then ''') union by name' else ''');' end from glob('n*.et');
.output
.header on
.mode duckbox
.read script.sql

方法2,在操作系统命令行使用管道操作

./duckdb141 -list -c "select 'from read_sheet('''||file||case when row_number()over()<> count()over()then ''') union by name' else ''');' end as \" \" from glob('n*.et')" | ./duckdb141 -unsigned -cmd "load '/par/rusty_sheet.duckdb_extension'" 

管道符前的部分也可以用-cmd来消除标题行, 就不必写as \" \" 用空格做标题了。

duckdb141 -list -cmd ".header off" -c "select 'from read_sheet('''||file||case when row_number()over()<> count()over()then ''') union by name' else ''');' end from glob('n*.et')"

这两种方法都能实现自动对多个xlsx文件union by name。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值